package com.jwipc.job.handler;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.base.Joiner;
import com.jwipc.job.dto.FtpResultDto;
import com.jwipc.job.logic.FileLogic;
import com.jwipc.job.util.FtpMultiThreadDownloader;
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.IAttachmentService;
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.time.LocalDateTime;
import java.util.*;

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

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

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

    @Value("${sys.ftp.host}")
    private String ftpHost;

    @Value("${sys.ftp.port}")
    private int ftpPort;

    @Value("${sys.ftp.userName}")
    private String ftpUser;

    @Value("${sys.ftp.password}")
    private String ftpPassword;

    @Autowired
    private FtpUtils ftpUtils;

    @Autowired
    private FileLogic fileLogic;

    @Autowired
    private IBusinessAttachmentService businessAttachmentService;

    @Autowired
    private ILogThirdPartyCallService logThirdPartyCallService;

    @Autowired
    private IAttachmentService attachmentService;

    @Autowired
    private IDeliveryOrderService deliveryOrderService;

    @Override
    public void interrupt() throws UnableToInterruptJobException {

    }

    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        log.info("****************FTP下载开始****************");
        long start = System.currentTimeMillis();
        StringBuilder stringBuilder = new StringBuilder();
        Date startTime = new Date(System.currentTimeMillis() - 5 * 24 * 60 * 60 * 1000); // 5天前
        Date endTime = new Date(); // 当前时间
        int maxThreads = 20; // 20线程并发
        // 指定FTP目录列表
        List<String> ftpDirectories = Arrays.asList(
                REMOTE_ROOT_DIR + "/C" + DateUtil.format(new Date(), "yyM"),
                REMOTE_ROOT_DIR + "/H" + DateUtil.format(new Date(), "yyM"),
                REMOTE_ROOT_DIR + "/Y" + DateUtil.format(new Date(), "yyM"),
                REMOTE_ROOT_DIR + "/X" + DateUtil.format(new Date(), "yyM")
        );
        log.info(StrUtil.format("指定FTP目录列表：{}\n", Joiner.on(",").join(ftpDirectories)));
        stringBuilder.append(StrUtil.format("指定FTP目录列表：{}\n", Joiner.on(",").join(ftpDirectories)));
        // 本地临时文件夹
        String localTempFileDir = StrUtil.concat(false, LOCAL_TEMP_FILE_DIR, File.separator, DateUtil.format(new Date(), "yyM"));
        File directory = new File(localTempFileDir);
        if (!directory.exists()) {
            directory.mkdirs();
        }
        stringBuilder.append(StrUtil.format("本地临时文件夹：{}\n", localTempFileDir));
        log.info(StrUtil.format("本地临时文件夹：{}\n", localTempFileDir));
        FtpMultiThreadDownloader downloader = new FtpMultiThreadDownloader(
                ftpHost, ftpPort, ftpUser, ftpPassword,
                localTempFileDir, startTime, endTime, maxThreads
        );
        try {
            //获取指定范围内的文件名
            List<Map<String, String>> fileInfos = downloader.getAllDateFiles(ftpDirectories);
            stringBuilder.append(StrUtil.format("获取指定范围内的文件信息：{}\n", Joiner.on(",").join(fileInfos)));
            log.info(StrUtil.format("获取指定范围内的文件信息：{}\n", Joiner.on(",").join(fileInfos)));
            List<Map<String, String>> needSaveFileList = Lists.newArrayList();
            if (CollectionUtil.isNotEmpty(fileInfos)) {
                //分批次去文件表里查询是否存在
                for (Map<String, String> fileInfo : fileInfos) {
                    String fileName = fileInfo.get("fileName");
                    BusinessAttachment attachment = businessAttachmentService.getOne(new LambdaQueryWrapper<BusinessAttachment>().eq(BusinessAttachment::getFileName, fileName).eq(BusinessAttachment::getBusinessTypeCode, "delivery_order").last(" LIMIT 1"));
                    if (ObjectUtil.isNull(attachment)) {
                        needSaveFileList.add(fileInfo);
                    }
                }
            }
            log.info(StrUtil.format("需要下载的文件信息：{}\n", Joiner.on(",").join(needSaveFileList)));
            stringBuilder.append(StrUtil.format("需要下载的文件信息：{}\n", Joiner.on(",").join(needSaveFileList)));




//            try {
//                // 调用下载方法
//                ftpUtils.newThreadDownloadFolder(needSaveFileList, localTempFileDir, this::processImage, 10);
//            } catch (IOException e) {
//                log.error("下载送货单失败", e);
//                return;
//            } catch (Exception e) {
//                log.error("处理请求异常", e);
//                return;
//            }
            downloader.downloadFiles(needSaveFileList);

            // 2 上传文件，并绑定业务关系
            List<FtpResultDto> allFiles = getAllFiles(localTempFileDir);
            List<String> existNo = Lists.newArrayList();
            List<String> noExistNo = Lists.newArrayList();
            List<String> suNo = Lists.newArrayList();

            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)) {
                            // 不存在的情况跳过
//                            fileLogic.safeDeleteTemplate(uploadFile);
                            noExistNo.add(orderCode);
                            continue;
                        }
                        existNo.add(orderCode);
                        // 2.2 推送到SRM文件服务器，返回文件信息
                        Attachment Attachment = fileLogic.uploadFile(uploadFile);
                        // 2.3 推送完删除临时文件
//                        fileLogic.safeDeleteTemplate(uploadFile);
                        // 2.4 创建业务附件关系
                        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);
                        suNo.add(orderCode);
                    }
                    businessAttachmentService.saveOrUpdateBatch(businessAttachmentList);
                } catch (Exception 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 logThirdPartyCall = new LogThirdPartyCall();
            logThirdPartyCall.setInfCode("ftp_down_order");
            logThirdPartyCall.setInfName("ftp下载送货单附件");
            logThirdPartyCall.setInfType(ThirdSysType.MES.getType());
            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下载结束****************");
        } finally {
            downloader.shutdown();
            // 3 最后删除整个文件夹
//            fileLogic.safeDeleteTemplate(new File(localTempFileDir));
        }

    }
    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.mkdirs();
        }

        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;
    }
}
