package com.cn.fdapfe.biz.service.impl;

import com.alibaba.fastjson2.JSON;
import com.cn.fdapfe.biz.domain.Data;
import com.cn.fdapfe.biz.service.IDataService;
import com.cn.fdapfe.web.controller.common.CommonController;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.cn.fdapfe.biz.domain.ModelDataGen;
import com.cn.fdapfe.biz.mapper.ModelDataGenMapper;
import com.cn.fdapfe.biz.service.IModelDataGenService;
import com.cn.fdapfe.common.utils.DateUtils;
import com.cn.fdapfe.common.utils.SecurityUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 物理模型数据生成管理Service业务层处理
 *
 * @author Allen
 * @date 2025-03-07
 */
@Service
public class ModelDataGenServiceImpl implements IModelDataGenService {
    private static final Logger logger = LoggerFactory.getLogger(ModelDataGenServiceImpl.class);

    @Resource
    private ModelDataGenMapper mapper;
    @Resource
    private IDataService dataService;

    @Resource
    private CommonController commonController;

    @Override
    public List<ModelDataGen> selectList(ModelDataGen po) {
        QueryWrapper<ModelDataGen> wrapper = buildQueryWrapper(po);
        wrapper.orderByDesc("create_time");
        return mapper.selectList(wrapper);
    }

    @Override
    public ModelDataGen selectOne(String id) {
        QueryWrapper<ModelDataGen> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(ModelDataGen::getDataGenId, id);
        return mapper.selectOne(wrapper);
    }
    /**
     * 将指定目录下的指定文件拷贝、重命名并移动到目标文件夹
     * @param sourceDirectory 源文件所在的目录
     * @param sourceFileName 源文件的名称
     * @param targetDirectory 目标文件夹
     * @param newFileName 重命名后的新文件名
     * @throws IOException 如果文件操作过程中出现 I/O 错误
     */
    public static String copyRenameAndMoveFile(String sourceDirectory, String sourceFileName,
                                             String targetDirectory, String newFileName) throws IOException {
        // 构建源文件的路径
        Path sourcePath = Paths.get(sourceDirectory, sourceFileName);
        // 构建目标文件的路径
        Path targetPath = Paths.get(targetDirectory, newFileName);

        // 检查源文件是否存在
        if (Files.exists(sourcePath)) {
            // 创建目标文件夹（如果不存在）
            Files.createDirectories(targetPath.getParent());
            // 拷贝文件并使用新的文件名
            Files.copy(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
            // 可以选择删除源文件以实现移动效果
             Files.delete(sourcePath);

        } else {
            System.out.println("源文件不存在: " + sourcePath);
        }
        return targetPath.toString();
    }


    @Override
    public int add(ModelDataGen po) {
            Data data = new Data();
            data.setType("0");
            data.setFileSuffix("csv");
        if(Objects.equals(po.getModelType(), "2")){
            try {
                // 远程启动大模型生成数据
                String path = new File(po.getModelPath()).getParent();
                writeToTxt(path + File.separator + "input" + File.separator + "input.txt", po.getBizParams());
                startExe(po.getModelPath());
                //处理模型生成文件
                String sourceDirectory = path + File.separator + "output";
                String sourceFileName = "output.csv";
                String targetDirectory = po.getOutputPath();
                String newFileName = po.getNewFileName();
                //生成文件处理后的新文件路径
                String newFilePath = copyRenameAndMoveFile(sourceDirectory, sourceFileName, targetDirectory, newFileName);
                data.setName(newFileName);
                data.setFileName(newFileName);
                data.setFilePath(newFilePath);
                dataService.insertData(data);
            } catch (Exception e) {
                logger.error("启动大模型或写入参数时出错", e);
                return 0;
            }
        }else{
            ObjectMapper objectMapper = new ObjectMapper();
            try {
                List<Map<String, Object>> objectList = objectMapper.readValue(po.getBizParams(),
                        new TypeReference<List<Map<String, Object>>>() {});
                for (Map<String, Object> jsonMap : objectList) {
                    String apiPath = extractLastPart(po.getModelPath(),"/");
                    String jsonString = JSON.toJSONString(jsonMap);
                    if (Objects.equals(apiPath, "zssc")) {
                        String filePath = (String) jsonMap.get("noise_data_file");
                        data.setFilePath(filePath);
                        data.setFileName(extractLastPart(filePath,"\\"));
                        data.setName(extractLastPart(filePath,"\\"));
                    }else if(Objects.equals(apiPath, "cssc")) {
                        String filePath = (String) jsonMap.get("test_data_file");
                        data.setFilePath(filePath);
                        data.setFileName(extractLastPart(filePath,"\\"));
                        data.setName(extractLastPart(filePath,"\\"));
                    }
                    boolean request = sendPostRequest(po.getModelPath(), jsonString);
                    if(request){
                        dataService.insertData(data);
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
//
        }
        ModelDataGen one = selectOne(po.getDataGenId());
        po.setCreateTime(DateUtils.getNowDate());
        po.setCreateBy(SecurityUtils.getUsername());
        return one != null ? update(po) : mapper.insert(po);
    }

    public static String extractLastPart(String url,String dom) {
        int lastSlashIndex = url.lastIndexOf(dom);
        if (lastSlashIndex != -1 && lastSlashIndex < url.length() - 1) {
            return url.substring(lastSlashIndex + 1);
        }
        return "";
    }
    @Override
    public int update(ModelDataGen po) {
        ModelDataGen one = selectOne(po.getDataGenId());
        setCreateInfo(po);
        return one != null ? mapper.updateById(po) : mapper.insert(po);
    }

    @Override
    public int delete(String[] ids) {
        if (ids == null || ids.length == 0) {
            return 0;
        }
        return ids.length == 1 ? mapper.deleteById(ids[0]) : mapper.deleteBatchIds(Arrays.asList(ids));
    }

    public static void startExe(String exePath) throws IOException, InterruptedException {
        ProcessBuilder processBuilder = new ProcessBuilder(exePath);
        Process process = processBuilder.start();
        int exitCode = process.waitFor();
        logger.info("程序退出码: {}", exitCode);
    }

    public static void writeToTxt(String filePath, String content) throws IOException {
        try (FileWriter writer = new FileWriter(filePath, false)) {
            writer.write("");
            writer.write(content);
            writer.flush();
        }
    }

    public static boolean sendPostRequest(String apiUrl, String jsonBody) throws IOException {
        URL url = new URL(apiUrl);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("POST");
        // 显式指定UTF-8编码
        connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
        connection.setDoOutput(true);

        byte[] requestBody = jsonBody.getBytes(StandardCharsets.UTF_8);
        connection.setRequestProperty("Content-Length", String.valueOf(requestBody.length));

        try (DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream())) {
            // 使用UTF-8编码写入字节
            outputStream.write(requestBody);
            outputStream.flush();
        }

        int responseCode = connection.getResponseCode();
        StringBuilder response = new StringBuilder();
        try (BufferedReader reader = new BufferedReader(
                // 显式指定UTF-8读取响应
                new InputStreamReader(
                        responseCode >= 200 && responseCode < 300 ?
                                connection.getInputStream() : connection.getErrorStream(),
                        StandardCharsets.UTF_8
                )
        )) {
            String line;
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }
        }
        logger.info("API 请求响应: {}", response);
        // 判断响应状态码是否在200 - 299之间
        return responseCode >= 200 && responseCode < 300;
    }

    private QueryWrapper<ModelDataGen> buildQueryWrapper(ModelDataGen po) {
        QueryWrapper<ModelDataGen> wrapper = new QueryWrapper<>();
        wrapper.like(StringUtils.isNotEmpty(po.getDataGenName()), "data_gen_name", po.getDataGenName())
                .eq(StringUtils.isNotEmpty(po.getModelId()), "model_id", po.getModelId())
                .eq(StringUtils.isNotEmpty(po.getStatus()), "status", po.getStatus())
                .eq(StringUtils.isNotEmpty(po.getDataGenId()), "data_gen_id", po.getDataGenId())
                .eq(StringUtils.isNotEmpty(po.getCreateBy()), "create_by", po.getCreateBy());
        if (po.getStartTime() != null) {
            wrapper.ge("start_time", po.getStartTime());
        }
        if (po.getEndTime() != null) {
            wrapper.le("end_time", po.getEndTime());
        }
        return wrapper;
    }

    private void setUpdateInfo(ModelDataGen po) {
        po.setUpdateBy(SecurityUtils.getUsername());
        po.setUpdateTime(DateUtils.getNowDate());
    }

    private void setCreateInfo(ModelDataGen po) {
        po.setCreateTime(DateUtils.getNowDate());
        po.setCreateBy(SecurityUtils.getUsername());
    }
}