package hw.tagApi.service.service.impl;

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.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 hw.tagApi.service.domain.ApiContent;
import org.springframework.transaction.annotation.Transactional;
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 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 = tagRecordService.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.CALLBACK_URL, ApiConstants.DATA_IMPORT);
        });

        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 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(ApiConstants.SELECT_STATUS, "系统错误");
                response.getFields().put(ApiConstants.DESCRIPTION, "查询条件必须包含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) {

                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());
                response.getFields().put("去向信息", data.getDestinationInfo() != null ? data.getDestinationInfo() : "");
                response.getFields().put("是否在库", data.getLibraryFlag() != null ? data.getLibraryFlag() : "");
                response.getFields().put("计划用途", data.getIntendedUse() != null ? data.getIntendedUse() : "");
                response.getFields().put("备注", data.getRemark() != null ? data.getRemark() : "");
                log.debug("查询结果详情 - ID: {}, 结果: {}", queryId, response.getFields());
            } else {
                log.info("未找到记录 - ID: {}", queryId);
                // 未找到记录
                response.getFields().put(ApiConstants.SELECT_STATUS, "未找到记录");
                if (fields.containsKey("筛选日期起点") && fields.containsKey("筛选日期终点")) {
                    String message = String.format("已遍历整个数据库，生产日期从%s到%s，未找到匹配的记录。",
                            fields.get("筛选日期起点"), fields.get("筛选日期终点"));
                    response.getFields().put(ApiConstants.DESCRIPTION, message);
                    log.debug("未找到记录详情 - ID: {}, 日期范围: {} - {}",
                            queryId, fields.get("筛选日期起点"), fields.get("筛选日期终点"));
                } else {
                    response.getFields().put(ApiConstants.DESCRIPTION, "未找到匹配的记录");
                }
            }

            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(ApiConstants.EXPORT_STATUS, "导出中");
            responseFields.put(ApiConstants.DESCRIPTION, "预计需要3分钟");
            response.setFields(responseFields);
            result.add(response);
        }

        // 异步执行导出任务
        executorService.execute(() -> {
            List<ApiContent> resApiContentList = new ArrayList<>();
            Date nowDate = new Date();
            for (ApiContent condition : content) {
                ApiContent response = new ApiContent();
                response.setId(condition.getId());
                try {
                    Map<String, Object> fields = condition.getFields();
                    String startDate = fields.get("筛选日期起点") != null ? (String) fields.get("筛选日期起点") : "";
                    String endDate = 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") : "";
                    String remark = fields.get("备注") != null ? (String) fields.get("备注") : "";
                    String lot = fields.get("LOT") != null ? (String) fields.get("LOT") : "";
                    String tagBatch = fields.get("标签批次号") != null ? (String) fields.get("标签批次号") : "";
                    String modelCode = fields.get("型号") != null ? (String) fields.get("型号") : "";
                    String destinationInfo = fields.get("去向信息") != null ? (String) fields.get("去向信息") : "";
                    String libraryFlag = fields.get("是否在库") != null ? (String) fields.get("是否在库") : "";
                    String intendedUse = fields.get("计划用途") != null ? (String) fields.get("计划用途") : "";
                    String batchNumber = fields.get("卷编号") != null ? (String) fields.get("卷编号") : "";

                    // 构建查询条件
                    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(modelCode)) {
                        queryCondition.setModelCode(modelCode);
                    }
                    if (StringUtils.hasText(TID)) {
                        queryCondition.setSelectTID(TID);
                    }
                    if (StringUtils.hasText(EPC)) {
                        queryCondition.setSelectEPC(EPC);
                    }
                    if (StringUtils.hasText(remark)) {
                        queryCondition.setRemark(remark);
                    }
                    if (StringUtils.hasText(destinationInfo)) {
                        queryCondition.setDestinationInfo(destinationInfo);
                    }
                    if (StringUtils.hasText(libraryFlag)) {
                        queryCondition.setLibraryFlag(libraryFlag);
                    }
                    if (StringUtils.hasText(intendedUse)) {
                        queryCondition.setIntendedUse(intendedUse);
                    }
                    if (StringUtils.hasText(batchNumber) && !batchNumber.contains("-")) {
                        queryCondition.setBatchNumber(batchNumber);
                    } else if (StringUtils.hasText(batchNumber) && batchNumber.contains("-")) {
                        List<String> batchNumberList = TagExcelUtil.splitHorizontalBarString(batchNumber, false);
                        queryCondition.setBatchNumberList(batchNumberList);
                    }
                    // 执行查询
                    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 {
                            SimpleDateFormat sDate = new SimpleDateFormat("yyyyMMdd-HHmm");
                            SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");

                            //组装数据
                            records.get(0).setTeamCenter("导出时间");
                            records.get(0).setDatabaseExport(sdf.format(nowDate));
                            int classNum = 0;
                            for (String string : fields.keySet()) {
                                classNum++;
                                if (records.size() <= classNum) {
                                    records.add(new HwTagRecord());
                                }
                                records.get(classNum).setTeamCenter(string);
                                records.get(classNum).setDatabaseExport(String.valueOf(fields.get(string)));
                            }

                            String fileName = String.format("团队中心-标签数据总库导出-%s.xlsx", sDate.format(nowDate));
                            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);
                            log.info("数据库导出完成 - ID: {}, 记录数: {}, 耗时: {}分{}秒", condition.getId(), records.size(), minutes, seconds);
                            responseFields.put(ApiConstants.EXPORT_STATUS, "导出成功");
                            responseFields.put(ApiConstants.DESCRIPTION, "耗时: " + 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(ApiConstants.EXPORT_STATUS, "导出失败");
                            responseFields.put(ApiConstants.DESCRIPTION, "生成导出文件失败: " + e.getMessage());
                        }
                    } else {
                        responseFields.put(ApiConstants.EXPORT_STATUS, "未找到记录");
                        responseFields.put(ApiConstants.DESCRIPTION, "未找到符合条件的记录");
                    }

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

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

        return result;
    }

    /**
     * 快速导入数据
     *
     * @param content 数据内容
     * @return 处理结果
     */
    @Override
    public List<ApiContent> fastImportDataList(List<ApiContent> content) {
        List<ApiContent> resList = new ArrayList<>();
        for (ApiContent apiContent : content) {
            long startTime = System.currentTimeMillis();
            ApiContent resContent = new ApiContent();
            resContent.setId(apiContent.getId());
            try {
                ApiContent result = tagRecordService.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));
        }
        return resList;
    }

    /**
     * 查改数据
     *
     * @param content 查改条件列表
     * @return 查改结果列表
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<ApiContent> checkReviseDataList(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();

            // 获取更新字段
            String upPassword = String.valueOf(fields.getOrDefault("改-密码", ""));
            String upOrderCode = String.valueOf(fields.getOrDefault("改-LOT", ""));
            String upTagBatch = String.valueOf(fields.getOrDefault("改-标签批次号", ""));
            String upModelCode = String.valueOf(fields.getOrDefault("改-型号", ""));
            String upDestinationInfo = String.valueOf(fields.getOrDefault("改-去向信息", ""));
            String upLibraryFlag = String.valueOf(fields.getOrDefault("改-是否在库", ""));
            String upIntendedUse = String.valueOf(fields.getOrDefault("改-计划用途", ""));
            String upRemark = String.valueOf(fields.getOrDefault("改-备注", ""));
            String upBatchNumber = String.valueOf(fields.getOrDefault("改-卷编号", ""));

            // 设置查询条件
            if (fields.containsKey("TID")) {
                String tid = (String) fields.get("TID");
                selectTagRecord.setSelectTID(tid);
            }
            if (fields.containsKey("EPC")) {
                String epc = (String) fields.get("EPC");
                selectTagRecord.setSelectEPC(epc);
            }
            if (fields.containsKey("密码")) {
                String password = (String) fields.get("密码");
                selectTagRecord.setPassword(password);
            }
            if (fields.containsKey("LOT")) {
                String orderCode = (String) fields.get("LOT");
                selectTagRecord.setOrderCode(orderCode);
            }
            if (fields.containsKey("标签批次号")) {
                String tagBatch = (String) fields.get("标签批次号");
                selectTagRecord.setTagBatch(tagBatch);
            }
            if (fields.containsKey("型号")) {
                String modelCode = (String) fields.get("型号");
                selectTagRecord.setModelCode(modelCode);
            }
            if (fields.containsKey("筛选日期起点")) {
                String startDate = (String) fields.get("筛选日期起点");
                selectTagRecord.setStartDate(startDate);
            }
            if (fields.containsKey("筛选日期终点")) {
                String endDate = (String) fields.get("筛选日期终点");
                selectTagRecord.setEndDate(endDate);
            }
            if (fields.containsKey("去向信息")) {
                String destinationInfo = (String) fields.get("去向信息");
                selectTagRecord.setDestinationInfo(destinationInfo);
            }
            if (fields.containsKey("是否在库")) {
                String libraryFlag = (String) fields.get("是否在库");
                selectTagRecord.setLibraryFlag(libraryFlag);
            }
            if (fields.containsKey("计划用途")) {
                String intendedUse = (String) fields.get("计划用途");
                selectTagRecord.setIntendedUse(intendedUse);
            }
            if (fields.containsKey("备注")) {
                String remark = (String) fields.get("备注");
                selectTagRecord.setRemark(remark);
            }
            if (fields.containsKey("卷编号")) {
                String batchNumber = (String) fields.get("卷编号");
                if (StringUtils.hasText(batchNumber) && !batchNumber.contains("-")) {
                    selectTagRecord.setBatchNumber(batchNumber);
                    log.info("设置查询条件 - 卷编号: {}", batchNumber);
                } else if (StringUtils.hasText(batchNumber) && batchNumber.contains("-")) {
                    List<String> batchNumberList = TagExcelUtil.splitHorizontalBarString(batchNumber, false);
                    selectTagRecord.setBatchNumberList(batchNumberList);
                    log.info("设置查询条件 - 卷编号范围: {}", batchNumberList);
                }
            }
            if (fields.containsKey("标签序号")) {
                String tagSequence = (String) fields.get("标签序号");
                if (StringUtils.hasText(tagSequence) && !tagSequence.contains("-")) {
                    selectTagRecord.setTagSequence(tagSequence);
                    log.info("设置查询条件 - 标签序号: {}", tagSequence);
                } else if (StringUtils.hasText(tagSequence) && tagSequence.contains("-")) {
                    List<String> tagSequenceList = TagExcelUtil.splitHorizontalBarString(tagSequence, true);
                    selectTagRecord.setTagSequenceList(tagSequenceList);
                    log.info("设置查询条件 - 标签序号范围: {}", tagSequenceList);
                }
            }

            // 执行查询
            log.info("执行数据库查询 - ID: {}", queryId);
            long startTime = System.currentTimeMillis();
            List<HwTagRecord> tagRecordList = tagRecordService.selectHwTagRecordList(selectTagRecord);
            int tagRecordListSize = tagRecordList.size();
            long endTime = System.currentTimeMillis();
            log.info("数据库查询完成 - ID: {}, 耗时: {}ms, 查询到记录数: {}", queryId, (endTime - startTime), tagRecordListSize);

            // 处理查询结果
            int successCount = 0;
            int failCount = 0;
            List<String> errorMessages = new ArrayList<>();
            Map<String, Object> responseFields = new HashMap<>();

            for (HwTagRecord tagRecord : tagRecordList) {
                try {
                    if (StringUtils.hasText(upPassword)) {
                        tagRecord.setPassword(upPassword);
                    }
                    if (StringUtils.hasText(upOrderCode)) {
                        tagRecord.setOrderCode(upOrderCode);
                    }
                    if (StringUtils.hasText(upBatchNumber)) {
                        tagRecord.setBatchNumber(upBatchNumber);
                    }
                    if (StringUtils.hasText(upTagBatch)) {
                        tagRecord.setTagBatch(upTagBatch);
                    }
                    if (StringUtils.hasText(upModelCode)) {
                        tagRecord.setModelCode(upModelCode);
                    }
                    if (StringUtils.hasText(upDestinationInfo)) {
                        tagRecord.setDestinationInfo(upDestinationInfo);
                    }
                    if (StringUtils.hasText(upLibraryFlag)) {
                        tagRecord.setLibraryFlag(upLibraryFlag);
                    }
                    if (StringUtils.hasText(upIntendedUse)) {
                        tagRecord.setIntendedUse(upIntendedUse);
                    }
                    if (StringUtils.hasText(upRemark)) {
                        tagRecord.setRemark(upRemark);
                    }
                    if (StringUtils.hasText(upBatchNumber)) {
                        tagRecord.setBatchNumber(upBatchNumber);
                    }
                    tagRecordService.updateHwTagRecordByTID(tagRecord);
                    successCount++;
                    log.info("更新成功 - TID: {}", tagRecord.getTId());
                } catch (Exception e) {
                    failCount++;
                    String errorMsg = String.format("更新失败 - TID: %s, 错误: %s", tagRecord.getTId(), e.getMessage());
                    errorMessages.add(errorMsg);

                    log.error(errorMsg, e);
                }
            }

            // 设置响应结果
            if (!errorMessages.isEmpty()) {
                responseFields.put(ApiConstants.CHECK_STATUS, "查改失败");
                responseFields.put(ApiConstants.DESCRIPTION, errorMessages);
                responseFields.put("查改记录数", tagRecordListSize);
            } else {
                responseFields.put(ApiConstants.CHECK_STATUS, "查改成功");
                responseFields.put(ApiConstants.DESCRIPTION, "");
                responseFields.put("查改记录数", tagRecordListSize);
            }
            response.setFields(responseFields);
            log.info("查改处理完成 - ID: {}, 成功: {}, 失败: {}", queryId, successCount, failCount);
            result.add(response);
        }
        return result;
    }


}
