package hw.tagApi.service.service.impl;

import hw.tagApi.common.utils.uuid.IdGenerator;
import hw.tagApi.service.service.IHwTagRecordService;
import hw.tagApi.service.service.IKDocsService;
import hw.tagApi.service.utils.TagExcelUtil;
import hw.tagApi.service.utils.httpClientUtils;
import java.time.Duration;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.*;

import hw.tagApi.service.constant.ApiConstants;
import hw.tagApi.service.domain.HwTagRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.ObjectMapper;
import hw.tagApi.service.domain.ApiResponse;
import hw.tagApi.service.domain.ApiContent;
import org.springframework.util.StringUtils;

/**
 * 云文档服务实现类
 *
 * @author Yinq
 * @date 2025-04-15
 */
@Service
public class KDocsServiceImpl implements IKDocsService {
    private static final Logger log = LoggerFactory.getLogger(KDocsServiceImpl.class);

    @Autowired
    private IHwTagRecordService tagRecordService;



    private static final int BATCH_SIZE = 100;

    // 创建线程池
    private static final ExecutorService executorService = new ThreadPoolExecutor(
            5,                      // 核心线程数
            10,                    // 最大线程数
            60L,                   // 空闲线程存活时间
            TimeUnit.SECONDS,      // 时间单位
            new LinkedBlockingQueue<>(100),  // 任务队列
            new ThreadPoolExecutor.CallerRunsPolicy()  // 拒绝策略：由调用线程处理
    );

    /**
     * 导入数据列表
     *
     * @param contentList 包含导入数据的ApiContent对象列表
     * @return 初始响应的ApiContent对象列表
     */
    @Override
    public List<ApiContent> importDataList(List<ApiContent> contentList) {
        List<ApiContent> resApiContentList = getApiContents(contentList);

        // 异步执行导入任务
        executorService.execute(() -> {
            List<ApiContent> resList = new ArrayList<>();
            for (ApiContent apiContent : contentList) {
                long startTime = System.currentTimeMillis();
                ApiContent resContent = new ApiContent();
                resContent.setId(apiContent.getId());
                try {
                    ApiContent result = this.importData(apiContent);
                    // 更新响应内容
                    resContent.setFields(result.getFields());
                } catch (Exception e) {
                    log.error("导入任务执行失败: {}", e.getMessage(), e);
                    Map<String, Object> errorFields = new HashMap<>();
                    errorFields.put(ApiConstants.IMPORT_STATUS, "系统错误");
                    errorFields.put(ApiConstants.DESCRIPTION, "导入任务执行失败: " + e.getMessage());
                    resContent.setFields(errorFields);
                }
                resList.add(resContent);
                long endTime = System.currentTimeMillis();
                log.info("数据库导入完成 - ID: {}, 耗时: {}ms", apiContent.getId(), (endTime - startTime));
            }

            // 发送处理结果到回调接口
            httpClientUtils.sendResultToCallback(resList, ApiConstants.IN_CALLBACK_URL);
        });

        return resApiContentList;
    }

    /**
     * 创建初始响应的ApiContent对象列表
     *
     * @param contentList 包含导入数据的ApiContent对象列表
     * @return 初始响应的ApiContent对象列表
     */
    private static List<ApiContent> getApiContents(List<ApiContent> contentList) {
        List<ApiContent> resApiContentList = new ArrayList<>();
        for (ApiContent apiContent : contentList) {
            // 创建初始响应
            Map<String, Object> resFields = new HashMap<>();
            resFields.put(ApiConstants.IMPORT_STATUS, "导入中");
            resFields.put(ApiConstants.DESCRIPTION, "后台处理中");
            ApiContent responseContent = new ApiContent();
            responseContent.setId(apiContent.getId());
            responseContent.setFields(resFields);
            resApiContentList.add(responseContent);
        }
        return resApiContentList;
    }

    /**
     * 导入数据
     *
     * @param apiContent 包含导入数据的ApiContent对象
     * @return 处理后的ApiContent对象
     */
    public ApiContent importData(ApiContent apiContent) {
        Map<String, Object> fields = apiContent.getFields();
        String importMode = String.valueOf(fields.get("导入模式"));
        String model = String.valueOf(fields.getOrDefault("型号", ""));
        String fileUrl = String.valueOf(fields.get("文件链接"));
        List<HwTagRecord> batchList = new ArrayList<>();
        Map<String, Object> resFields = new HashMap<>();
        apiContent.setFields(resFields);
        try {
            log.info("开始处理文件，URL: {}", fileUrl);

            // 获取文件字节数组
            byte[] fileData = httpClientUtils.getByteArrayFromUrl(fileUrl);
            if (fileData == null) {
                log.error("获取文件失败");
                resFields.put(ApiConstants.IMPORT_STATUS, "系统错误");
                resFields.put(ApiConstants.DESCRIPTION, "获取文件失败");
                return apiContent;
            }

            // 解析Excel数据
            try (ByteArrayInputStream bis = new ByteArrayInputStream(fileData)) {
                Map<String, Object> excelResult = TagExcelUtil.parseTagExcel(bis);
                if (!excelResult.containsKey("tagList")) {
                    log.error("解析Excel文件失败，未找到标签数据");
                    resFields.put(ApiConstants.IMPORT_STATUS, "导入失败");
                    resFields.put(ApiConstants.DESCRIPTION, "解析Excel文件失败，未找到标签数据");
                    return apiContent;
                }
                // 获取订单信息
                Map<String, String> orderInfo = (Map<String, String>) excelResult.get("orderInfo");
                // 获取标签数据列表
                List<Map<String, String>> tagList = (List<Map<String, String>>) excelResult.get("tagList");
                // 获取文件名
                String fileName = (String) excelResult.get("fileName");
                // 批量处理标签数据
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                for (Map<String, String> tagData : tagList) {
                    HwTagRecord record = new HwTagRecord();
                    record.setOrderCode(orderInfo.get("orderNo"));
                    record.setBatchNumber(orderInfo.get("batchNo"));
                    record.setOperatorId(orderInfo.get("operatorId"));
                    record.setProcessingTime(sdf.parse(orderInfo.get("processTime")));
                    record.setTotalQuantity(Long.valueOf(orderInfo.get("totalCount")));
                    // 设置标签数据
                    record.setModelCode(model);
                    record.setTagSequence(tagData.get("序号"));
                    record.setTId(tagData.get("TID"));
                    record.setEpc(tagData.get("EPC"));
                    record.setPassword(tagData.get("密码"));
                    record.setTestResult(tagData.get("测试结果"));
                    record.setTestValue(tagData.get("测试值"));
                    record.setReferenceValue(tagData.get("参考值"));
                    record.setTestingTime(sdf.parse(tagData.get("测试时间")));
                    record.setFileName(fileName);

                    // 达到批量大小时执行插入
                    if ("更新".equals(importMode)) {
                        tagRecordService.updateHwTagRecordByTID(record);
                        continue;
                    }
                    //校验tId唯一
                    HwTagRecord tagRecord = tagRecordService.selectHwTagRecordByTID(record.getTId());
                    if (tagRecord != null) {
                        continue;
                    }
                    record.setRId(IdGenerator.nextId());
                    // 添加到批处理列表
                    batchList.add(record);
                    if (batchList.size() >= BATCH_SIZE) {
                        tagRecordService.batchInsertHwTagRecord(batchList);
                        log.info("批量插入{}条数据成功", batchList.size());
                        batchList.clear();
                    }
                }

                // 处理剩余的数据
                if (!batchList.isEmpty()) {
                    tagRecordService.batchInsertHwTagRecord(batchList);
                    log.info("批量插入剩余{}条数据成功", batchList.size());
                    batchList.clear();
                }
                resFields.put(ApiConstants.IMPORT_STATUS, "导入完成");
            }
        } catch (Exception e) {
            log.error("处理文件失败: {}", e.getMessage(), e);
            resFields.put(ApiConstants.IMPORT_STATUS, "系统错误");
            resFields.put(ApiConstants.DESCRIPTION, e.getMessage());
        }

        return apiContent;
    }

    @Override
    public String getSystemStatus() {
        try {
            ApiResponse response = new ApiResponse();
            response.setCaseCode("10");
            // 添加导入模式信息
            ApiContent modeContent = new ApiContent();
            Map<String, String> modeFields = new HashMap<>();
            modeFields.put(ApiConstants.DESCRIPTION, "");
            // 使用ObjectMapper将对象转换为JSON字符串
            ObjectMapper mapper = new ObjectMapper();
            return mapper.writeValueAsString(response);
        } catch (Exception e) {
            log.error("生成系统状态响应失败", e);
            return null;
        }
    }

    /**
     * 查询数据
     *
     * @param content 查询条件列表
     * @return 查询结果列表
     */
    @Override
    public List<ApiContent> queryDataList(List<ApiContent> content) {
        List<ApiContent> result = new ArrayList<>();
        if (content == null || content.isEmpty()) {
            log.warn("查询条件列表为空");
            return result;
        }

        log.info("开始处理查询请求，查询条件数量: {}", content.size());
        for (ApiContent query : content) {
            String queryId = query.getId();
            log.info("处理查询条件 ID: {}, 查询参数: {}", queryId, query.getFields());
            
            ApiContent response = new ApiContent();
            response.setId(queryId);
            response.setFields(new HashMap<>());
            Map<String, Object> fields = query.getFields();
            HwTagRecord selectTagRecord = new HwTagRecord();
            
            // 检查查询条件
            if (!fields.containsKey("TID") && !fields.containsKey("EPC")) {
                log.warn("查询条件错误 - ID: {}, 缺少必要的查询参数(TID或EPC)", queryId);
                response.getFields().put("搜索状态", "查询条件错误");
                response.getFields().put("情况说明", "查询条件必须包含TID或EPC");
                result.add(response);
                continue;
            }

            // 设置查询条件
            if (fields.containsKey("TID")) {
                String tid = (String) fields.get("TID");
                selectTagRecord.setTId(tid);
            }
            if (fields.containsKey("EPC")) {
                String epc = (String) fields.get("EPC");
                selectTagRecord.setEpc(epc);
            }
            if (fields.containsKey("搜索日期起点")) {
                String startDate = (String) fields.get("搜索日期起点");
                selectTagRecord.setStartDate(startDate);
            }
            if (fields.containsKey("搜索日期终点")) {
                String endDate = (String) fields.get("搜索日期终点");
                selectTagRecord.setEndDate(endDate);
            }

            // 执行查询
            log.info("执行数据库查询 - ID: {}", queryId);
            long startTime = System.currentTimeMillis();
            HwTagRecord data = tagRecordService.selectHwTagRecordData(selectTagRecord);
            long endTime = System.currentTimeMillis();
            log.info("数据库查询完成 - ID: {}, 耗时: {}ms", queryId, (endTime - startTime));

            // 处理查询结果
            if (data != null) {
                log.info("查询成功 - ID: {}, TID: {}, EPC: {}", queryId, data.getTId(), data.getEpc());
                // 查询成功
                response.getFields().put("搜索状态", "搜索成功");
                response.getFields().put("TID", data.getTId());
                response.getFields().put("EPC", data.getEpc());
                response.getFields().put("标签序号", data.getTagSequence());
                response.getFields().put("密码", data.getPassword() != null ? data.getPassword() : "");
                response.getFields().put("RID", data.getTId());
                response.getFields().put("LOT", data.getOrderCode());
                response.getFields().put("卷编号", data.getBatchNumber());
                response.getFields().put("本卷数量", data.getTotalQuantity() != null ? data.getTotalQuantity() : "");
                response.getFields().put("标签批次号", data.getTagBatch() != null ? data.getTagBatch() : "");
                response.getFields().put("型号", data.getModelCode() != null ? data.getModelCode() : "");
                response.getFields().put("加工时间", new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(data.getProcessingTime()));
                response.getFields().put("生产人员编号", data.getOperatorId());
                log.debug("查询结果详情 - ID: {}, 结果: {}", queryId, response.getFields());
            } else {
                log.info("未找到记录 - ID: {}", queryId);
                // 未找到记录
                response.getFields().put("搜索状态", "未找到记录");
                if (fields.containsKey("搜索日期起点") && fields.containsKey("搜索日期终点")) {
                    String message = String.format("已遍历整个数据库，生产日期从%s到%s，未查询到该TID。",
                        fields.get("搜索日期起点"), fields.get("搜索日期终点"));
                    response.getFields().put("情况说明", message);
                    log.debug("未找到记录详情 - ID: {}, 日期范围: {} - {}", 
                        queryId, fields.get("搜索日期起点"), fields.get("搜索日期终点"));
                } else {
                    response.getFields().put("情况说明", "未找到匹配的记录");
                }
            }

            result.add(response);
        }

        return result;
    }

    /**
     * 导出数据
     * 
     * @param content 导出条件列表
     * @return 导出结果列表
     */
    @Override
    public List<ApiContent> exportDataList(List<ApiContent> content) {
        List<ApiContent> result = new ArrayList<>();
        if (content == null || content.isEmpty()) {
            log.warn("导出条件列表为空");
            return result;
        }
        log.info("开始处理导出请求，导出条件数量: {}", content.size());
        // 创建初始响应
        for (ApiContent condition : content) {
            ApiContent response = new ApiContent();
            response.setId(condition.getId());
            Map<String, Object> responseFields = new HashMap<>();
            responseFields.put("导出状态", "导出中");
            responseFields.put("情况说明", "预计需要3分钟");
            response.setFields(responseFields);
            result.add(response);
        }
        
        // 异步执行导出任务
        executorService.execute(() -> {
            List<ApiContent> resApiContentList = new ArrayList<>();
            for (ApiContent condition : content) {
                ApiContent response = new ApiContent();
                response.setId(condition.getId());
                try {
                    Map<String, Object> fields = condition.getFields();
                    String lot = fields.get("LOT") != null ? (String) fields.get("LOT") : "";
                    String startDate = fields.get("导出日期起点") != null ? (String) fields.get("导出日期起点") : "";
                    String endDate = fields.get("导出日期终点") != null ? (String) fields.get("导出日期终点") : "";
                    String tagBatch = fields.get("标签批次号") != null ? (String) fields.get("标签批次号") : "";
                    String batchNumber = fields.get("卷编号") != null ? (String) fields.get("卷编号") : "";
                    String modelCode = fields.get("型号") != null ? (String) fields.get("型号") : "";
                    String TID = fields.get("TID") != null ? (String) fields.get("TID") : "";
                    String EPC = fields.get("EPC") != null ? (String) fields.get("EPC") : "";

                    // 构建查询条件
                    HwTagRecord queryCondition = new HwTagRecord();
                    if (StringUtils.hasText(lot)) {
                        queryCondition.setOrderCode(lot);
                    }
                    if (StringUtils.hasText(startDate)) {
                        queryCondition.setStartDate(startDate);
                    }
                    if (StringUtils.hasText(endDate)) {
                        queryCondition.setEndDate(endDate);
                    }
                    if (StringUtils.hasText(tagBatch)) {
                        queryCondition.setTagBatch(tagBatch);
                    }
                    if (StringUtils.hasText(batchNumber)) {
                        queryCondition.setBatchNumber(batchNumber);
                    }
                    if (StringUtils.hasText(modelCode)) {
                        queryCondition.setModelCode(modelCode);
                    }
                    if (StringUtils.hasText(TID)) {
                        queryCondition.setSelectTID(TID);
                    }
                    if (StringUtils.hasText(EPC)) {
                        queryCondition.setSelectEPC(EPC);
                    }
                    // 执行查询
                    log.info("执行数据导出查询 - ID: {}", condition.getId());
                    long startTime = System.currentTimeMillis();
                    List<HwTagRecord> records = tagRecordService.selectHwTagRecordList(queryCondition);

                    
                    Map<String, Object> responseFields = new HashMap<>();
                    
                    if (records != null && !records.isEmpty()) {
                        try {
                            String fileName = String.format("标签数据_%s.xlsx", condition.getId());
                            String filePath = TagExcelUtil.generateTagExcel(records, fileName);
                            long endTime = System.currentTimeMillis();
                            Duration duration = Duration.ofMillis(endTime - startTime);
                            long minutes = duration.toMinutes();
                            long seconds = duration.minusMinutes(minutes).getSeconds();
                            Date futureDate = new Date(endTime + ApiConstants.PASS_TIME);
                            SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
                            log.info("数据库导出完成 - ID: {}, 记录数: {}, 耗时: {}分{}秒", condition.getId(), records.size(), minutes, seconds);
                            responseFields.put("导出状态", "导出成功");
                            responseFields.put("情况说明", "耗时: " + minutes + "分" + seconds + "秒");
                            responseFields.put("文件路径", filePath);
                            responseFields.put("链接有效期", sdf.format(futureDate));
                            log.info("导出文件生成成功 - ID: {}, 路径: {}", condition.getId(), filePath);
                        } catch (Exception e) {
                            log.error("生成导出文件失败 - ID: {}", condition.getId(), e);
                            responseFields.put("导出状态", "导出失败");
                            responseFields.put("情况说明", "生成导出文件失败: " + e.getMessage());
                        }
                    } else {
                        responseFields.put("导出状态", "未找到记录");
                        responseFields.put("情况说明", "未找到符合条件的记录");
                    }
                    
                    response.setFields(responseFields);

                } catch (Exception e) {
                    log.error("处理导出任务失败 - ID: {}", condition.getId(), e);
                    response.setId(condition.getId());
                    Map<String, Object> responseFields = new HashMap<>();
                    responseFields.put("导出状态", "导出失败");
                    responseFields.put("情况说明", "处理导出任务失败: " + e.getMessage());
                    response.setFields(responseFields);

                }
                resApiContentList.add(response);
            }
            // 发送处理结果到回调接口
            httpClientUtils.sendResultToCallback(resApiContentList, ApiConstants.OUT_CALLBACK_URL);
        });
        
        return result;
    }
}
