package org.springblade.system.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.springblade.common.core.domain.entity.KyDataClassify;
import org.springblade.common.core.domain.entity.KyDataClassifyVo;
import org.springblade.common.core.domain.entity.KyDataCollectData;
import org.springblade.system.domain.vo.DaKyProFilesContentsVo;
import org.springblade.system.mapper.FileShareMapper;
import org.springblade.system.service.FileManageService;
import org.springblade.system.service.FileShareService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.Base64;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author：liang.chao
 * @Date：2025/10/23 - 14:43
 */
@Service
public class FileShareServiceImpl implements FileShareService {

    @Resource
    private FileShareMapper fileShareMapper;
    @Resource
    private FileManageService fileManageService;

    @Value("${bonus.profile}")
    private String uploadDir;


    @Override
    public List<KyDataClassifyVo> listAll(KyDataClassify kyDataClassify) {
        //获取父级
        List<KyDataClassifyVo> KyDataClassifyVoList = fileShareMapper.getParenList();
        if (KyDataClassifyVoList.size() > 0) {
            //获取子级
            for (KyDataClassifyVo kyDataClassifyVo : KyDataClassifyVoList) {
                kyDataClassify.setPid(kyDataClassifyVo.getCode());
                List<KyDataClassify> kyDataClassifyList = fileShareMapper.listAll(kyDataClassify);
                kyDataClassifyVo.setKyDataClassifyList(kyDataClassifyList);
            }
        }
        return KyDataClassifyVoList;
    }

    @Override
    public List<KyDataCollectData> selectKyDataCollectDataList(KyDataCollectData kyDataCollectData) {
        return fileShareMapper.selectKyDataCollectDataList(kyDataCollectData);
    }


    @Override
    public void queryDetailById(KyDataCollectData kyDataCollectData, HttpServletResponse response) {
        try {
            String jsonData = fileShareMapper.queryDetailById(kyDataCollectData);
            if (jsonData != null) {
                JSONArray objects = JSON.parseArray(jsonData);
                for (Object obj : objects) {
                    JSONObject object = (JSONObject) obj;
                    if (object != null) {
                        String id = object.getString("id");
                        if (id.equals(kyDataCollectData.getJsonId().toString())) {
                            DaKyProFilesContentsVo record = fileManageService.getFileById(Long.parseLong(id));

                            if (record == null || StringUtils.isBlank(record.getFilePath())) {
                                response.setStatus(HttpStatus.NOT_FOUND.value());
                                return;
                            }

                            String safeFullPath = buildSecureFullPath(uploadDir, record.getFilePath());
                            if (safeFullPath == null) {
                                response.setStatus(HttpStatus.BAD_REQUEST.value());
                                return;
                            }

                            File file = new File(safeFullPath);
                            if (!file.exists() || !file.isFile()) {
                                response.setStatus(HttpStatus.NOT_FOUND.value());
                                return;
                            }

                            // 设置响应头
                            String contentType = getContentType(record.getSuffixName());
                            response.setContentType(contentType);
                            String encodedFileName = URLEncoder.encode(record.getFileName(), String.valueOf(StandardCharsets.UTF_8))
                                    .replaceAll("\\+", "%20");
                            response.setHeader("Content-Disposition", "inline; filename*=UTF-8''" + encodedFileName);

                            // 写入文件流到响应
                            Files.copy(file.toPath(), response.getOutputStream());
                            response.flushBuffer();
                            return;
                        }
                    }
                }
            }
            response.setStatus(HttpStatus.NOT_FOUND.value());
        } catch (Exception e) {
            response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
        }
    }

    private String getContentType(String suffix) {
        if (StringUtils.isBlank(suffix)) {
            return "application/octet-stream";
        }

        switch (suffix.toLowerCase()) {
            case "jpg":
            case "jpeg":
                return "image/jpeg";
            case "png":
                return "image/png";
            case "gif":
                return "image/gif";
            case "bmp":
                return "image/bmp";
            case "webp":
                return "image/webp";
            case "svg":
                return "image/svg+xml";
            default:
                return "application/octet-stream";
        }
    }

    private String buildSecureFullPath(String baseDir, String filePath) {
        if (StringUtils.isBlank(filePath)) {
            return null;
        }

        // 统一路径分隔符
        String unifiedPath = filePath.replace('\\', '/');

        // 移除开头的斜杠
        unifiedPath = unifiedPath.replaceAll("^/+", "");

        // 检查路径遍历
        if (unifiedPath.contains("../") || unifiedPath.contains("..\\")) {
            return null;
        }

        // 检查绝对路径
        if (unifiedPath.matches("^[a-zA-Z]:/.*") || unifiedPath.startsWith("/")) {
            return null;
        }

        // 构建完整路径
        String fullPath;
        if (baseDir.endsWith(File.separator)) {
            fullPath = baseDir + unifiedPath;
        } else {
            fullPath = baseDir + File.separator + unifiedPath;
        }

        // 使用File的getCanonicalPath进行最终验证
        try {
            File canonicalFile = new File(fullPath);
            String canonicalPath = canonicalFile.getCanonicalPath();

            // 验证是否仍在基础目录内
            String canonicalBaseDir = new File(baseDir).getCanonicalPath();
            if (!canonicalPath.startsWith(canonicalBaseDir)) {
                return null;
            }

            return canonicalPath;
        } catch (IOException e) {
            return null;
        }
    }
}
