package com.jwipc.job.handler;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.base.Joiner;
import com.jwipc.exception.DaoException;
import com.jwipc.job.dto.FtpResultDto;
import com.jwipc.job.logic.FileLogic;
import com.jwipc.job.util.FtpUtils;
import com.jwipc.log.constant.ThirdSysType;
import com.jwipc.order.entity.DeliveryOrder;
import com.jwipc.order.service.IDeliveryOrderService;
import com.jwipc.sys.entity.Attachment;
import com.jwipc.sys.entity.BusinessAttachment;
import com.jwipc.sys.entity.LogThirdPartyCall;
import com.jwipc.sys.service.IBusinessAttachmentService;
import com.jwipc.sys.service.ILogThirdPartyCallService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.locks.ReentrantLock;

/**
 * <p>
 *  SRM从工厂文件服务器增量获取送货单
 *      ①送货单抬头表增加字段“送货单附件”；
 *      ②每天增量获取送货单附件；
 *      ③获取附件保存后，每个文件生成一个唯一文件ID，并根据附件文件名匹配对应的送货单，将文件ID更新至送货单表字段“送货单附件”。
 * </p>
 *
 * @author Chen Tianshi
 * @since 2025/9/10 13:58
 */
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
@Slf4j
@Component
public class NewDailyPullAndPushDeliveryOrderFileJob extends QuartzJobBean implements InterruptableJob {

    @Value("${sys.ftp.localTempFileDir}")
    private String LOCAL_TEMP_FILE_DIR;

    @Value("${sys.ftp.remoteRootDir}")
    private String REMOTE_ROOT_DIR;

    @Autowired
    private FtpUtils ftpUtils;

    @Autowired
    private FileLogic fileLogic;

    @Autowired
    private IBusinessAttachmentService businessAttachmentService;

    @Autowired
    private IDeliveryOrderService deliveryOrderService;
    @Autowired
    private ILogThirdPartyCallService logThirdPartyCallService;

    // 使用静态锁，确保所有实例共享同一把锁
    private static final ReentrantLock lock = new ReentrantLock();

    @Override
    public void interrupt() throws UnableToInterruptJobException {

    }

    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        // 尝试获取锁，防止重复执行（即使有多个 JobDetail 或手动触发）
        if (!lock.tryLock()) {
            log.warn("Job is already running. Skipping duplicate execution.");
            return;
        }

        try {
            // 检查是否被中断（支持 InterruptableJob）
            if (Thread.currentThread().isInterrupted()) {
                log.info("Job was interrupted before execution.");
                return;
            }
            log.info("****************FTP下载开始****************");
            long start = System.currentTimeMillis();
            StringBuilder stringBuilder = new StringBuilder();
            Date startDate = new Date(System.currentTimeMillis() - 30L * 24 * 60 * 60 * 1000); // 5天前
            Date endDate = new Date(System.currentTimeMillis() +  24 * 60 * 60 * 1000);// 当前时间

            // 自动计算线程数
            int threadCount = Math.max(10, Runtime.getRuntime().availableProcessors() * 2);

            // 格式化日期用于日志
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String dateStr = sdf.format(startDate);

            // 本地临时文件夹
            String localTempFileDir = StrUtil.concat(false, LOCAL_TEMP_FILE_DIR, File.separator, dateStr);
            // FTP服务器文件夹
            SimpleDateFormat sdfFileY = new SimpleDateFormat("yy");
            SimpleDateFormat sdfFileM = new SimpleDateFormat("M");



            //举例：10月为25A,11月为25B，12月为25C
            String year = sdfFileY.format(startDate);
            String month = sdfFileM.format(startDate).equals("10")?"A":sdfFileM.format(startDate).equals("11")?"B":sdfFileM.format(startDate).equals("12")?"C":sdfFileM.format(startDate);
            String startDateSdf = StrUtil.format("{}{}", year, month);

            String year1 = sdfFileY.format(endDate);
            String month1 = sdfFileM.format(endDate).equals("10")?"A":sdfFileM.format(endDate).equals("11")?"B":sdfFileM.format(endDate).equals("12")?"C":sdfFileM.format(endDate);
            String endDateSdf = StrUtil.format("{}{}", year1, month1);

            List<String> remoteDirList = new ArrayList<>();
            remoteDirList.add(REMOTE_ROOT_DIR + "/C" + startDateSdf);// 例：/rcvbill - 快捷方式/送货单扫描/C259
            remoteDirList.add(REMOTE_ROOT_DIR + "/H" + startDateSdf);// 例：/rcvbill - 快捷方式/送货单扫描/C259
            remoteDirList.add(REMOTE_ROOT_DIR + "/Y" + startDateSdf);// 例：/rcvbill - 快捷方式/送货单扫描/C259
            remoteDirList.add(REMOTE_ROOT_DIR + "/X" + startDateSdf);// 例：/rcvbill - 快捷方式/送货单扫描/C259
            if (!startDateSdf.equals(endDateSdf)){
                remoteDirList.add(REMOTE_ROOT_DIR + "/C" + endDateSdf);// 例：/rcvbill - 快捷方式/送货单扫描/C259
                remoteDirList.add(REMOTE_ROOT_DIR + "/H" + endDateSdf);// 例：/rcvbill - 快捷方式/送货单扫描/C259
                remoteDirList.add(REMOTE_ROOT_DIR + "/Y" + endDateSdf);// 例：/rcvbill - 快捷方式/送货单扫描/C259
                remoteDirList.add(REMOTE_ROOT_DIR + "/X" + endDateSdf);// 例：/rcvbill - 快捷方式/送货单扫描/C259
            }
            log.info(StrUtil.format("指定FTP目录列表：{}\n", Joiner.on(",").join(remoteDirList)));
            stringBuilder.append(StrUtil.format("指定FTP目录列表：{}\n", Joiner.on(",").join(remoteDirList)));
            stringBuilder.append(StrUtil.format("本地临时文件夹：{}\n", localTempFileDir));
            log.info(StrUtil.format("本地临时文件夹：{}\n", localTempFileDir));
//        for (String remoteDir : remoteDirList){
            log.info("开始下载前一天的送货单: {}, 远程目录: {}, 本地目录: {}", dateStr, remoteDirList, localTempFileDir);
            try {
                // 调用下载方法
                ftpUtils.threadDownloadFilesByDateRangeList(remoteDirList, localTempFileDir, this::processImage,
                        threadCount, startDate, endDate, stringBuilder);
            } catch (IOException e) {
                log.error("下载送货单失败", e);
                stringBuilder.append(StrUtil.format("下载送货单失败：{}\n", e));
                return;
            } catch (Exception e) {
                log.error("处理请求异常", e);
                stringBuilder.append(StrUtil.format("处理请求异常：{}\n", e));
                return;
            }
            // 2 上传文件，并绑定业务关系
            List<FtpResultDto> allFiles = getAllFiles(localTempFileDir);
            List<String> existNo = Lists.newArrayList();
            List<String> noExistNo = Lists.newArrayList();
            List<String> suNo = Lists.newArrayList();
            log.info(StrUtil.format("需要下载的文件信息：{}\n", Joiner.on(",").join(allFiles)));
            stringBuilder.append(StrUtil.format("需要下载的文件信息：{}\n", Joiner.on(",").join(allFiles)));
            LogThirdPartyCall logThirdPartyCall = new LogThirdPartyCall();
            logThirdPartyCall.setInfCode("ftp_down_order");
            logThirdPartyCall.setInfName("ftp下载送货单附件");
            logThirdPartyCall.setInfType(ThirdSysType.MES.getType());
            if (CollectionUtil.isNotEmpty(allFiles)) {
                log.info("开始上传到SRM文件服务器，并绑定送货单");
                try {
                    List<BusinessAttachment> businessAttachmentList = Lists.newArrayList();
                    for (FtpResultDto file : allFiles) {
                        File uploadFile = file.getFile();
                        // 2.1 获取送货单信息
                        String orderCode= file.getFileName().substring(0, 12);  // 送货单号
                        DeliveryOrder deliveryOrder = deliveryOrderService.getOne(new LambdaQueryWrapper<DeliveryOrder>().eq(DeliveryOrder::getOrderCode, orderCode));
                        if (Objects.isNull(deliveryOrder)) {
                            // 不存在的情况跳过
                            noExistNo.add(orderCode);
//                            fileLogic.safeDeleteTemplate(uploadFile);
                            continue;
                        }
                        existNo.add(orderCode);
                        if (uploadFile == null || !uploadFile.exists() || uploadFile.length() == 0) {
                            continue;
                        }
                        // 2.2 推送到SRM文件服务器，返回文件信息
                        Attachment Attachment = fileLogic.uploadFile(uploadFile);
                        // 2.3 推送完删除临时文件
//                        fileLogic.safeDeleteTemplate(uploadFile);
                        // 2.4 创建业务附件关系
                        BusinessAttachment oldBusinessAttachment = businessAttachmentService.getOne(new LambdaQueryWrapper<BusinessAttachment>()
                                .eq(BusinessAttachment::getBusinessCode, orderCode)
                                .eq(BusinessAttachment::getBusinessTypeCode, "delivery_order")
                                .eq(BusinessAttachment::getFileName, Attachment.getFileName())
                        );
                        if (oldBusinessAttachment != null){
                            continue;
                        }
                        BusinessAttachment insertData = new BusinessAttachment();
                        insertData.setFileId(Attachment.getId());
                        insertData.setFileName(Attachment.getFileName());
                        //如果开头为T，也是退货单
                        insertData.setType(file.getFileName().contains("TH")||file.getFileName().startsWith("T") ? "return_order" : "delivery_order");
                        insertData.setBusinessId(deliveryOrder.getId());
                        insertData.setBusinessCode(orderCode);
                        insertData.setBusinessTypeCode("delivery_order");
                        insertData.setCreateTime(LocalDateTime.now());
                        insertData.setCreateUser(1L);
                        insertData.setUpdateTime(LocalDateTime.now());
                        insertData.setUpdateUser(1L);
                        businessAttachmentList.add(insertData);
//                        businessAttachmentService.save(insertData);
                        suNo.add(orderCode);
                    }
                    businessAttachmentService.saveOrUpdateBatch(businessAttachmentList);

                } catch (Exception e) {
                    stringBuilder.append(StrUtil.format("文件上传失败：{}\n", e));
                    log.error("文件上传失败", e);
                } finally {
                    log.info("结束上传");
                }
                stringBuilder.append(StrUtil.format("系统存在的送货单：{}\n", CollUtil.isEmpty(existNo) ? "无" : Joiner.on(",").join(existNo)));
                stringBuilder.append(StrUtil.format("系统不存在的送货单：{}\n", CollUtil.isEmpty(noExistNo) ? "无" : Joiner.on(",").join(noExistNo)));
                stringBuilder.append(StrUtil.format("处理成功的送货单：{}\n", CollUtil.isEmpty(suNo) ? "无" : Joiner.on(",").join(suNo)));

                long end = System.currentTimeMillis();



                logThirdPartyCall.setInfRequestParams(stringBuilder.toString());
                logThirdPartyCall.setInfResponse("ok");
                logThirdPartyCall.setInfInfo(StrUtil.format("请求耗时：{}秒\n", (end - start) / 1000));
                logThirdPartyCall.setInfResult(1);
                logThirdPartyCall.setInfCallTime(LocalDateTime.now());
                logThirdPartyCallService.save(logThirdPartyCall);
                log.info("****************FTP下载结束****************");
                // 3 最后删除整个文件夹
//                fileLogic.safeDeleteTemplate(new File(localTempFileDir));
            } else {
                log.info("远程目录: {},前一天暂无新增送货单", remoteDirList);
                long end = System.currentTimeMillis();
                logThirdPartyCall.setInfRequestParams(stringBuilder.toString());
                logThirdPartyCall.setInfResponse("没有需要下载的附件");
                logThirdPartyCall.setInfInfo(StrUtil.format("请求耗时：{}秒\n", (end - start) / 1000));
                logThirdPartyCall.setInfResult(0);
                logThirdPartyCall.setInfCallTime(LocalDateTime.now());
                logThirdPartyCallService.save(logThirdPartyCall);
            }

        } finally {
            lock.unlock(); // 确保释放锁
        }
        // 1.先从FTP拉取送货单文件
        // 计算前一天的时间范围
//        Calendar calendar = Calendar.getInstance();
//        calendar.add(Calendar.DAY_OF_YEAR, -1); // 前一天
//        calendar.set(Calendar.YEAR, 2025);
//        calendar.set(Calendar.MONTH, 7);
//        calendar.set(Calendar.DATE, 11);
//        calendar.set(Calendar.HOUR_OF_DAY, 0);
//        calendar.set(Calendar.MINUTE, 0);
//        calendar.set(Calendar.SECOND, 0);
//        calendar.set(Calendar.MILLISECOND, 0);
//        Date startDate = calendar.getTime(); // 前一天00:00:00
//
//        calendar.set(Calendar.HOUR_OF_DAY, 23);
//        calendar.set(Calendar.MINUTE, 59);
//        calendar.set(Calendar.SECOND, 59);
//        calendar.set(Calendar.MILLISECOND, 999);
//        Date endDate = calendar.getTime(); // 前一天23:59:59.999

//        }
    }
    private void processImage(File imageFile) {}

    private List<FtpResultDto> getAllFiles(String dir) {
        List<FtpResultDto> fileList = new ArrayList<>();
        File directory = new File(dir);

        if (!directory.exists() || !directory.isDirectory()) {
            log.error("目录不存在或不是有效目录: {}", dir);
            return fileList;
        }

        File[] files = directory.listFiles();
        if (files == null) return null;
        for (File file : files) {
            FtpResultDto ftpResultDto = new FtpResultDto();
            ftpResultDto.setFile(file);
            ftpResultDto.setFileName(file.getName());
            fileList.add(ftpResultDto);
        }
        return fileList;
    }
}
