package cn.superdesk.uniorder.controller._thirdpart.jd.bak;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileReader;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.lang.UUID;
import cn.superdesk.uniorder.common.enums.accounting.AccountingOrderDimCreateByEnum;
import cn.superdesk.uniorder.common.enums.thirdpart.jd.SysQuartzScheduleTaskStatementOfAccountIsPauseEnum;
import cn.superdesk.uniorder.common.excel.converters.szhtxx.CustomStringBigDecimalConverter;
import cn.superdesk.uniorder.common.exception.UnifiedOrderRuntimeException;
import cn.superdesk.uniorder.common.exception.constants.ExceptionMsg;
import cn.superdesk.uniorder.common.json.AnJsonUtils;
import cn.superdesk.uniorder.common.rest.response.R;
import cn.superdesk.uniorder.common.rest.response.ResponseResultOuterUtils;
import cn.superdesk.uniorder.controller.base.BaseController;
import cn.superdesk.uniorder.dto._constant.ResourceConstant;
import cn.superdesk.uniorder.dto.param.accounting.jd.AccountingUnifiedSupplierOrderJdImportFullVersionExcelRow;
import cn.superdesk.uniorder.dto.param.accounting.jd.AccountingUnifiedSupplierOrderJdImportLiteVersionExcelRow;
import cn.superdesk.uniorder.dto.param.scheduler.SysQuartzScheduleTaskStatementOfAccountJdParam;
import cn.superdesk.uniorder.dto.param.scheduler.SysQuartzScheduleTaskStatementOfAccountJdRunExcelImportForm;
import cn.superdesk.uniorder.dubbo.consumer._common.ProviderEnvConstantDubboCustomerService;
import cn.superdesk.uniorder.dubbo.consumer.scheduler.SysQuartzScheduleTaskStatementOfAccountJdDubboConsumerService;
import cn.superdesk.uniorder.dubbo.consumer.thirdpart.jd.AccountingUnifiedSupplierOrderJdDubboConsumerService;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.read.metadata.ReadSheet;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.Objects;


/**
 * @Description: 第三方-szhtxx-深圳航天信息有限公司-e6软件
 * @Author: linjinyu
 * @CreateDate: 2021/3/17 上午9:45
 * @UpdateUser: linjinyu
 * @UpdateDate: 2021/3/17 上午9:45
 * @UpdateRemark: 修改内容
 * @Version: 1.0
 */
@Api(value = "第三方-jd-京东对账-金采Excel", tags = {"第三方-jd-京东对账-金采Excel"})
@Slf4j
@RestController
@RequestMapping("/thirdpart/jd/reconciliation_schedule/")
public class ThirdPartJdReconciliationScheduleController extends BaseController {

    @Autowired
    private SysQuartzScheduleTaskStatementOfAccountJdDubboConsumerService sysQuartzScheduleTaskStatementOfAccountJdDubboConsumerService;

    @Autowired
    private AccountingUnifiedSupplierOrderJdDubboConsumerService accountingUnifiedSupplierOrderJdDubboConsumerService;

    @Resource
    private ProviderEnvConstantDubboCustomerService providerEnvConstantDubboCustomerService;

    @Resource
    private Snowflake snowflake;


    /**
     * http://192.168.6.223:8089/web/thirdpart/jd/reconciliation_schedule/store/excel/and/create/task
     *
     * @param multipartFile
     * @return
     * @throws Exception
     */
    @ApiOperation(value = "供应商结算-京东对账-op列表-op导入账单(上传excel与表单)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "statementOfAccountType", value = "账单类型:京东 对账单类型 1-客户结算;2-供应商结算;21-供应商结算-京东; 所以传21", paramType = "form", required = true, dataType = "Integer"),

            @ApiImplicitParam(name = "saleId", value = "供应商Id(外部)", paramType = "form", required = true, dataType = "Long"),

            @ApiImplicitParam(name = "excelFile", value = "导入账单", paramType = "form", required = true, dataType = "MultipartFile"),

            @ApiImplicitParam(name = "cycleBeginTime", value = "账单周期 日期范围 开始日期 eg 2021-10-01", paramType = "form", required = true, dataType = "String"),
            @ApiImplicitParam(name = "cycleEndTime", value = "账单周期 日期范围 开始日期 eg 2021-10-31", paramType = "form", required = true, dataType = "String"),

            @ApiImplicitParam(name = "thirdPartAccountingOrderSn", value = "账单编号(第三方)", paramType = "form", required = true, dataType = "String"),
            @ApiImplicitParam(name = "remark", value = "备注", paramType = "form", required = false, dataType = "String")
    })
    @RequestMapping(value = "store/excel/and/create/task", method = RequestMethod.POST)
    @ResponseBody
    public R<String> excelImportAndStore(
            @RequestParam(value = "statementOfAccountType") Integer statementOfAccountType,

            @RequestParam(value = "saleId") Long saleId,

            @RequestParam(value = "excelFile") MultipartFile multipartFile,

            @RequestParam(value = "cycleBeginTime") String cycleBeginTimeStr,
            @RequestParam(value = "cycleEndTime") String cycleEndTimeStr,

            @RequestParam(value = "thirdPartAccountingOrderSn") String thirdPartAccountingOrderSn,
            @RequestParam(value = "remark") String remark,

            @RequestParam(value = "dateFormat", defaultValue = "yyyy-MM-dd HH:mm:ss") String dateFormat
    ) throws Exception {
//		yyyy-MM-dd
//		yyyy-MM-dd HH:mm:ss
//		2021-08-01 00:00:00
//		2021-08-31 23:59:59
        Date cycleBeginTime = DateUtil.parse(cycleBeginTimeStr + " " + "00:00:00", dateFormat);
        Date cycleEndTime   = DateUtil.parse(cycleEndTimeStr + " " + "23:59:59", dateFormat);

//		cycleEndTime = DateUtil.endOfDay(cycleEndTime);

        log.info("\n{}\n{}\n{}\n{}", cycleBeginTimeStr, cycleEndTimeStr, cycleBeginTime, cycleEndTime);


        ResourceConstant excelExportConstant = providerEnvConstantDubboCustomerService.getResourceConstant();

        String excelExportPathRoot             = excelExportConstant.getPathRoot();
        String excelExportRelativePathTemplate = excelExportConstant.getPathTemplate();
        String excelExportRelativePathStorage  = excelExportConstant.getPathStorage();

        String relativePath = File.separator + "upload" +
                File.separator + "thirdpart" +
                File.separator + "jd" +
                File.separator + "import" +
                File.separator + "reconciliation_schedule" +
                File.separator;

        String currentDate = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));

        String targetFullPath = excelExportPathRoot + relativePath + currentDate + File.separator;

        if (!FileUtil.exist(targetFullPath)) {
            FileUtil.mkdir(targetFullPath);
        }

        String originalFilename = multipartFile.getOriginalFilename();
        String fileName         = UUID.randomUUID().toString() + "@" + multipartFile.getOriginalFilename();
        String suffix           = Objects.requireNonNull(multipartFile.getOriginalFilename()).substring(multipartFile.getOriginalFilename().lastIndexOf(".") + 1);

        String targetRelativePathAndFileName = relativePath + currentDate + File.separator + fileName;

        File file1 = FileUtil.writeBytes(multipartFile.getBytes(), targetFullPath + fileName);

        log.info("\n{}\n{}\n{}\n{}", originalFilename, fileName, suffix, targetRelativePathAndFileName);

        if (!fileName.matches("^.+\\.(?i)(xls)$") && !fileName.matches("^.+\\.(?i)(xlsx)$")) {
            throw new UnifiedOrderRuntimeException(ExceptionMsg.SYS_ERROR.getCode(), "上传文件格式不正确");
        }

        boolean isExcel2003 = true;
        if (fileName.matches("^.+\\.(?i)(xlsx)$")) {
            isExcel2003 = false;
        }

        // TODO 添加任务


        String batchId = snowflake.nextIdStr();

        SysQuartzScheduleTaskStatementOfAccountJdParam form = SysQuartzScheduleTaskStatementOfAccountJdParam
                .builder()
                .batchId(batchId)

                // 此不是说来源是商品维度,而是说用商品维度去产生对账单 订单维度只有老版本才用
                .dimCreateBy(AccountingOrderDimCreateByEnum.商品.getKey())

                .statementOfAccountName(originalFilename)
                // 对账单类型 1-客户结算;2-供应商结算;21-供应商结算-京东;
                .statementOfAccountType(statementOfAccountType)
                .thirdPartAccountingOrderSn(thirdPartAccountingOrderSn)
                .remark(remark)

                .serviceNo("666")

                .sysOrgId(0L)
                .sysVirtId(0L)
                .outOrgId(0L)
                .outVirtId(0L)

                .sysMerchantId(0L)
                .outMerchantId(saleId)

                .cycleBeginTime(cycleBeginTime)
                .cycleEndTime(cycleEndTime)

                .isPause(SysQuartzScheduleTaskStatementOfAccountIsPauseEnum.启用.getKey())
                .jobId(0L)

                // 产品(③支持任务状态下拉查询:任务状态:待执行、执行中、执行成功、执行失败) 说明 前端上传完Excel与提交完表单后 后端创建任务 任务状态为 待执行 |
                .runState(0)
                .runTime(DateUtil.date())
                .processState(0)
                // .processTime()
                .checkState(0)
                // .checkTime()
                .accountingStatus(0)
                // .accountingTime()
                // .finishTime()
                // .accountingOrderSn()
                .params(AnJsonUtils.toJson(SysQuartzScheduleTaskStatementOfAccountJdRunExcelImportForm
                        .builder()
                        .batchId(batchId)
                        .excelExportPathRoot(excelExportPathRoot)
                        .excelExportRelativePathTemplate(excelExportRelativePathTemplate)
                        .excelExportRelativePathStorage(excelExportRelativePathStorage)
                        .originalFilename(originalFilename)
                        .fileName(fileName)
                        .suffix(suffix)
                        .relativePath(relativePath)
                        .currentDate(currentDate)
                        .targetRelativePathAndFileName(targetRelativePathAndFileName)
                        .build()
                ))
                //		.result()
//		.paramsSnapshot()
                .build();


        int ret = sysQuartzScheduleTaskStatementOfAccountJdDubboConsumerService.addSysQuartzScheduleTaskStatementOfAccountJd(form, getToken());


        if (ret == 0) {
            return ResponseResultOuterUtils.createErrorResult("500", "失败");
        } else {
            return ResponseResultOuterUtils.createSuccesResult("成功");
        }
    }

    /**
     * 此功能定义为 从excel文件导入数据
     * TODO 如果此 batchId 已经导入过 就要先删除这个记录
     * http://192.168.6.223:8089/web/thirdpart/jd/reconciliation_schedule/import/excel/from/storage
     *
     * @param form
     * @return
     * @throws Exception
     */
    @ApiOperation(value = "供应商结算-京东对账-op列表-op导入账单(上传excel与表单)-op手动导入数据(完整版 Full version)")
    @RequestMapping(value = "import/excel/fullVersion/storage", method = RequestMethod.POST)
    @ResponseBody
    public R<String> excelImportFullVersion(@RequestBody SysQuartzScheduleTaskStatementOfAccountJdRunExcelImportForm form) throws Exception {


        // TODO 如果此 batchId 已经导入过 就要先删除这个记录

        ResourceConstant resourceConstant = providerEnvConstantDubboCustomerService.getResourceConstant();

        String excelExportPathRoot             = resourceConstant.getPathRoot();
        String excelExportRelativePathTemplate = resourceConstant.getPathTemplate();
        String excelExportRelativePathStorage  = resourceConstant.getPathStorage();

        String targetFullPath = excelExportPathRoot + form.getTargetRelativePathAndFileName();

        ExcelReader excelReader = null;

        FileReader fileReader = new FileReader(targetFullPath);

        try {
            excelReader = EasyExcel.read(
                    fileReader.getInputStream(),
                    AccountingUnifiedSupplierOrderJdImportFullVersionExcelRow.class,
                    new ThirdPartJdReconciliationScheduleFullVersionExcelRowImportDataListener(
                            accountingUnifiedSupplierOrderJdDubboConsumerService,
                            snowflake,
                            form.getBatchId(),
                            getToken()
                    ))
                    .registerConverter(new CustomStringBigDecimalConverter())
                    .build();
            ReadSheet readSheet = EasyExcel.readSheet(0).build();
            excelReader.read(readSheet);

        } finally {

            if (excelReader != null) {
                // 这里千万别忘记关闭,读的时候会创建临时文件,到时磁盘会崩的
                excelReader.finish();
            }
        }

        return ResponseResultOuterUtils.createSuccesResult();
    }

    /**
     * 此功能定义为 从excel文件导入数据
     * TODO 如果此 batchId 已经导入过 就要先删除这个记录
     * http://192.168.6.2:8089/web/thirdpart/jd/reconciliation_schedule/import/excel/liteVersion/storage
     *
     * @param form
     * @return
     * @throws Exception
     */
    @ApiOperation(value = "供应商结算-京东对账-op列表-op导入账单(上传excel与表单)-op手动导入数据(精简版 Lite version)")
    @RequestMapping(value = "import/excel/liteVersion/storage", method = RequestMethod.POST)
    @ResponseBody
    public R<String> excelImportLiteVersion(@RequestBody SysQuartzScheduleTaskStatementOfAccountJdRunExcelImportForm form) throws Exception {


        // TODO 如果此 batchId 已经导入过 就要先删除这个记录

        ResourceConstant resourceConstant = providerEnvConstantDubboCustomerService.getResourceConstant();

        String excelExportPathRoot             = resourceConstant.getPathRoot();
        String excelExportRelativePathTemplate = resourceConstant.getPathTemplate();
        String excelExportRelativePathStorage  = resourceConstant.getPathStorage();

        String targetFullPath = excelExportPathRoot + form.getTargetRelativePathAndFileName();

        ExcelReader excelReader = null;

        FileReader fileReader = new FileReader(targetFullPath);

        try {
            excelReader = EasyExcel.read(
                    fileReader.getInputStream(),
                    AccountingUnifiedSupplierOrderJdImportLiteVersionExcelRow.class,
                    new ThirdPartJdReconciliationScheduleLiteVersionExcelRowImportDataListener(
                            accountingUnifiedSupplierOrderJdDubboConsumerService,
                            snowflake,
                            form.getBatchId(),
                            getToken()
                    ))
                    .registerConverter(new CustomStringBigDecimalConverter())
                    .build();
            ReadSheet readSheet = EasyExcel
                    .readSheet(0)
                    .build();
            excelReader.read(readSheet);

        } finally {

            if (excelReader != null) {
                // 这里千万别忘记关闭,读的时候会创建临时文件,到时磁盘会崩的
                excelReader.finish();
            }
        }

        return ResponseResultOuterUtils.createSuccesResult();
    }


    /**
     * 步骤3:通过京东的订单数据-比对统一订单数据-生成报告
     * http://192.168.6.2:8089/web/thirdpart/jd/reconciliation_schedule/check/up
     *
     * @param form
     * @return
     * @throws Exception
     */
    @ApiOperation(value = "供应商结算-京东对账-op列表-op导入账单(上传excel与表单)-op手动导入数据-步骤3:通过京东的订单数据-比对统一订单数据-生成报告")
    @RequestMapping(value = "check/up", method = RequestMethod.POST)
    @ResponseBody
    public R<String> checkUp(@RequestBody SysQuartzScheduleTaskStatementOfAccountJdRunExcelImportForm form) throws Exception {

        sysQuartzScheduleTaskStatementOfAccountJdDubboConsumerService.opCheckUp(form);

        return ResponseResultOuterUtils.createSuccesResult();
    }


    @ApiOperation(value = "供应商结算-京东对账-op列表-op导入账单(上传excel与表单)-op手动导入数据-步骤3:通过报告的异常数据-重新比对统一订单数据-生成报告")
    @RequestMapping(value = "check/up/exception", method = RequestMethod.POST)
    @ResponseBody
    public R<String> checkUpException(@RequestBody SysQuartzScheduleTaskStatementOfAccountJdRunExcelImportForm form) throws Exception {

        sysQuartzScheduleTaskStatementOfAccountJdDubboConsumerService.opCheckUpException(form);

        return ResponseResultOuterUtils.createSuccesResult();
    }

    // TODO 按扭操作 @link cn.superdesk.uniorder.controller.scheduler.SysQuartzScheduleTaskStatementOfAccountJdFieldAccountingStatusController
}
