package com.dxhy.core.thread;


import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.dxhy.api.model.config.Business;
import com.dxhy.api.model.excelExport.TDxExcelExportlog;
import com.dxhy.common.rabbitmq.RabbitMqSender;
import com.dxhy.common.service.impl.TabulateRedisServiceImpl;
import com.dxhy.common.util.ExcelPoiUtil;
import com.dxhy.common.util.ExceptionUtil;
import com.dxhy.common.util.JsonUtils;
import com.dxhy.common.util.StringHelper;
import com.dxhy.common.utils.DateUtils;
import com.dxhy.core.feign.IFeginWebsocket;
import com.dxhy.core.model.BbfpzhcxRespVO;
import com.dxhy.core.service.export.FpzhcxService;
import com.dxhy.core.service.singletable.IExcelExportlogService;
import com.dxhy.core.service.ywgl.YwglService;
import com.dxhy.core.util.JsonResponseUtils;
import com.dxhy.oss.service.FileService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.*;

/**
 * @description  发票数量统计表查询导出
 * @author  Allen
 * @date    2024/5/13 17:08
*/
@SuppressWarnings({"AlibabaMethodTooLong", "DuplicatedCode", "FieldCanBeLocal"})
@Slf4j

public class FpsltjbExportThread extends BaseThread {

    /**
     * 默认要导出第几页的数据
     */
    private final int default_curr = 1;
    /**
     * 默认每页导出多少条数据
     */
    private final int default_size = 5000;
    /**
     * 文件名前缀
     */
    private final String fileNamePrefix = "发票数量统计表导出";
    /**
     * 文件名后缀
     */
    private final String fileNameSurfix = ".xlsx";
    /**
     * 文件名中间分隔符
     */
    private final String fileSplit = "_";
    /**
     * excel的标题
     */
    private final String title = "发票数量统计表";
    /**
     * 导出excel的列名
     */
    private String[] titleColumns = {"购方名称", "购方税号", "年月", "发票类型", "发票总数", "正常", "失控", "作废", "异常", "冲红","部分冲红", "全额冲红", "红字发票待确认"};

    private final IExcelExportlogService exportLogService;

    private final List<TDxExcelExportlog> exportLogs;

    private final YwglService ywglService;

    private final FileService fileService;

    private final RabbitMqSender sender;
    private final TabulateRedisServiceImpl tabulateRedisService;

    public FpsltjbExportThread(IExcelExportlogService exportLogService, List<TDxExcelExportlog> exportLogs,
                               YwglService ywglService, FileService fileService, RabbitMqSender sender, IFeginWebsocket feginWebsocket,
                               TabulateRedisServiceImpl tabulateRedisService) {
        this.exportLogService = exportLogService;
        this.exportLogs = exportLogs;
        this.ywglService = ywglService;
        this.fileService = fileService;
        this.sender = sender;
        this.feginWebsocket = feginWebsocket;
        this.tabulateRedisService = tabulateRedisService;
    }

    private final IFeginWebsocket feginWebsocket;

    @Override
    public void run() {
        for (TDxExcelExportlog exportLog : exportLogs) {
            // 日志表主键
            Long id = exportLog.getId();
            String userid = exportLog.getUserAccount();

            String userName = exportLog.getUserName();
            // 导出条件

            String condition = exportLog.getConditions();
            // 数据源名称
            String dbName = exportLog.getDbName();
            if (StringHelper.isBlank(dbName)) {
                dbName = "";
            }
            String createDate = DateUtils.dateToStrLong(exportLog.getCreateDate());
            JSONObject msg = new JSONObject();

            // 捕获异常，防止某一条日志导出出错，影响其它日志的导出
            try {
                exportLogService.updateStart(id, dbName);
                // 参数转换为需要的形式
                Map<String, String> pramsMap = JsonUtils.getInstance().fromJson(condition,Map.class);

                // 导出文件名
                StringBuilder ftpFileName = new StringBuilder();
                ftpFileName.append(userid);
                ftpFileName.append(fileSplit);
                ftpFileName.append(fileNamePrefix);
                ftpFileName.append(fileSplit);
                ftpFileName.append(DateUtils.getStringDateShort());
                ftpFileName.append(fileSplit);
                ftpFileName.append((new Date()).getTime());
                ftpFileName.append(fileNameSurfix);

                // 本地文件存储路径
                StringBuilder excelFile = new StringBuilder();
                excelFile.append(fileService.getLocalPathDefault());
                excelFile.append(ftpFileName.toString());

                // 递归导出数据到excel
                this.processExportData(pramsMap, excelFile.toString(), titleColumns);

                // FTP文件存储路径
                String[] toDay = DateUtil.today().split("-");
                String ftpFilePath = fileService.getPathPrefix() + userName + "/" + "excelFile/" + toDay[0] + "/"
                    + toDay[1] + "/" + toDay[2] + "/" + ftpFileName.toString();
                // 文件上传ftp
                fileService.uploadFile(ftpFilePath, excelFile.toString());

                // 设置成功消息内容
                msg.put("title", super.getSuccTitle(title));
                msg.put("content", super.getSuccContent(createDate));
                msg.put("url", super.getUrl(id));
                msg.put("useraccount", userName);
                // 记录导出完成状态
                exportLogService.updateSucc(id, ftpFilePath, dbName);
            } catch (Exception e) {
                String errmsg = ExceptionUtil.getExceptionDeteil(e, 4000);
                // 设置失败消息内容
                msg.put("title", super.getFailTitle(title));
                msg.put("content", super.getFailContent(createDate, errmsg));
                msg.put("url", "");
                msg.put("useraccount", userName);

                log.error("", e);
                // 记录导出出错状态
                exportLogService.updateFail(id, errmsg, dbName);
            } finally {
                // 发送导出消息到mq
                String responseResult = JsonResponseUtils.responseResult(msg);
                sender.sendToMsg(responseResult);

                // 申请成功后像websocket发送申请信息
                feginWebsocket.setMessageToWebsocket(userName);
            }
        }
    }

    /**
     * 递归导出数据到excel文件，防止jvm oom
     *
     * @param pramsMap
     *            查询数据参数集合
     * @param excelFile
     *            导出的文件
     * @throws Exception
     *             异常
     *
     */

    private void processExportData(Map<String, String> pramsMap, String excelFile, String[] titleColumns)
        throws Exception {
        // 查询指定数据
        List<Map<String, String>> tjjgs = ywglService.getTjjg(pramsMap);
        List<List<String>> dataList = new ArrayList<>();
        tjjgs.stream().forEach(tjjg->{
            List<String> data = new ArrayList<>();
            data.add(tjjg.get("gfmc"));
            data.add(tjjg.get("gfsh"));
            data.add(tjjg.get("time"));
            data.add(tjjg.get("fplxmc"));
            data.add(tjjg.get("fpzsl"));
            data.add(tjjg.get("zcfpsl"));
            data.add(tjjg.get("skfpsl"));
            data.add(tjjg.get("zffpsl"));
            data.add(tjjg.get("ycfpsl"));
            data.add(tjjg.get("chfpsl"));
            data.add(tjjg.get("bfchfpsl"));
            data.add(tjjg.get("qbchfpsl"));
            data.add(tjjg.get("hzfpdqrsl"));
            dataList.add(data);
        });
        ExcelPoiUtil.exportToExcelNoPage(excelFile, title, dataList, titleColumns);
    }
}
