package com.xdap.self_development.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.exception.ExcelAnalysisException;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;
import com.xdap.api.moudle.user.pojo.XdapUsers;
import com.xdap.self_development.common.BusinessDatabase;
import com.xdap.self_development.controller.request.DataEntryEngineModelExcel;
import com.xdap.self_development.domain.enums.DistributeStatusEnum;
import com.xdap.self_development.domain.enums.ParamValueVersionEnum;
import com.xdap.self_development.domain.pojo.DataEntryEngineModelPojo;
import com.xdap.self_development.domain.pojo.EngineParamDetailPojo;
import com.xdap.self_development.domain.pojo.ParameterPojo;
import com.xdap.self_development.exception.ExcelImportException;
import com.xdap.self_development.service.EngineParamDetailService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;

import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;


@Slf4j
//@Component
//@Scope("prototype")
public class EngineModelListener implements ReadListener<DataEntryEngineModelExcel> {
    private final BusinessDatabase businessDatabase;
    private final EngineParamDetailService engineParamDetailService;
    private static final int BATCH_COUNT = 1000;
    private final String ycOrOt;
    private static final Integer VERSION_NUMBER = 1;
    private final XdapUsers usersPojo;


    private final List<DataEntryEngineModelExcel> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

    public EngineModelListener(BusinessDatabase businessDatabase, EngineParamDetailService engineParamDetailService, String ycOrOt, XdapUsers usersPojo) {
        this.businessDatabase = businessDatabase;
        this.engineParamDetailService = engineParamDetailService;
        this.usersPojo = usersPojo;
        this.ycOrOt = ycOrOt;
    }

    @Override
    public void invoke(DataEntryEngineModelExcel engineModelPojo, AnalysisContext analysisContext) throws ExcelAnalysisException {
        engineModelPojo.setSheetName(analysisContext.readSheetHolder().getSheetName());
        engineModelPojo.setRowIndex(analysisContext.readRowHolder().getRowIndex() + 1);
        cachedDataList.add(engineModelPojo);
    }

    /**
     * 校验逻辑
     *
     */
    private void dataStrictly(List<DataEntryEngineModelExcel> cachedDataList) {

        if (ObjectUtils.isEmpty(cachedDataList)) {
            log.error("机型数据为空");
            throw new ExcelImportException(
                    "Excel无数据"
            );
        }

        for (DataEntryEngineModelExcel data : cachedDataList) {
            String sheetName = data.getSheetName();
            Integer rowIndex = data.getRowIndex();
            //productNumber，modelName，brand
            List<DataEntryEngineModelPojo> modelPojos = businessDatabase.getBusinessDatabase()
                    .eq("product_number", data.getProductNumber())
                    .eq("model_name", data.getModelName())
//                    .eq("brand", data.getBrand())
                    .doQuery(DataEntryEngineModelPojo.class);
            if (ObjectUtils.isNotEmpty(modelPojos)) {
                throw new ExcelImportException(
                        String.format("请检查该型号是否已经存在,%s页第%d行", sheetName, rowIndex)
                );
            }
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {

        dataStrictly(cachedDataList);
        // 存储到数据库
        if (!ObjectUtils.isEmpty(cachedDataList)) {
            saveData();
        }
        log.info("所有数据解析完成！");
    }

    public void saveData() {

        ArrayList<DataEntryEngineModelPojo> modelPojos = new ArrayList<>();

        List<ParameterPojo> parameters = engineParamDetailService.selectAllByNewVersion();
        //写入机型
        for (DataEntryEngineModelExcel modelExcel : cachedDataList) {
            DataEntryEngineModelPojo modelPojo = new DataEntryEngineModelPojo();
            BeanUtils.copyProperties(modelExcel, modelPojo, "status");

            //获取状态码
            DistributeStatusEnum byDesc = DistributeStatusEnum.getByDesc("未分发");
            modelPojo.setDistributeStatus(byDesc != null ? byDesc.getCode() : null);
            modelPojo.setYcOrOth(ycOrOt);
            modelPojo.setParameterNum(parameters.toArray().length);
            modelPojo.setMaintainedParameterNum(0);
            modelPojo.setVersionNumber(VERSION_NUMBER);
            modelPojo.setIsDelete(0);
            modelPojo.setCreatedBy(usersPojo.getId());
            modelPojo.setLastUpdatedBy("");
            modelPojo.setLastUpdateDate(Timestamp.valueOf(LocalDateTime.now()));
            modelPojo.setCreationDate(Timestamp.valueOf(LocalDateTime.now()));
            modelPojo.setId(UUID.randomUUID().toString());
            modelPojos.add(modelPojo);
            if (Objects.equals(ycOrOt, "竞品")) {
                modelPojo.setManufacturerName(modelExcel.getManufacturerName());
                modelPojo.setManufacturerAbbreviation(modelExcel.getManufacturerAbbreviation());
                try {
                    DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                    LocalDate localDate = LocalDate.parse(modelExcel.getProductionDate(), dateTimeFormatter);
                    Date date = Date.from(localDate.atStartOfDay(java.time.ZoneId.systemDefault()).toInstant());
                    modelPojo.setProductionDate(date);
                } catch (Exception e) {
                    log.error("生产日期格式错误", e);
                }
            }
        }
        businessDatabase.getBusinessDatabase().doBatchInsert(modelPojos);

        saveDataParamDetail(modelPojos, parameters);
    }

    //为每个机型绑定参数
    private void saveDataParamDetail(ArrayList<DataEntryEngineModelPojo> modelPojos, List<ParameterPojo> parameters) {
        Map<String, ParameterPojo> uniqueParamsMap = new LinkedHashMap<>();
        for (ParameterPojo parameter : parameters) {
            String key = parameter.getParameterName() + "_" + parameter.getPartsName() + "_" + parameter.getSubsystemName();
            uniqueParamsMap.putIfAbsent(key, parameter);
        }
        List<ParameterPojo> uniqueParameters = new ArrayList<>(uniqueParamsMap.values());
        
        List<EngineParamDetailPojo> engineParamDetailPojos = new ArrayList<>();
        for (DataEntryEngineModelPojo modelPojo : modelPojos) {
            if (Objects.equals(modelPojo.getYcOrOth(), "玉柴")) {
                for (ParameterPojo parameter : uniqueParameters) {
                    EngineParamDetailPojo engineParamDetailPojo = new EngineParamDetailPojo();
                    engineParamDetailPojo.setEngineModelId(modelPojo.getId());
                    engineParamDetailPojo.setParameterId(parameter.getId());
                    engineParamDetailPojo.setSubsystemName(parameter.getSubsystemName());
                    engineParamDetailPojo.setParameterType(parameter.getParameterType());
                    engineParamDetailPojo.setPartsName(parameter.getPartsName());
                    engineParamDetailPojo.setParameterName(parameter.getParameterName());
                    engineParamDetailPojo.setParameterSource(parameter.getParameterSource());
                    engineParamDetailPojo.setDepartment(parameter.getDepartment());
                    engineParamDetailPojo.setMajorVersion(VERSION_NUMBER);
                    engineParamDetailPojo.setVersionStatus(ParamValueVersionEnum.DRAFT.getCode());
                    engineParamDetailPojo.setCreatedBy(usersPojo.getId());
                    engineParamDetailPojo.setLastUpdatedBy("");
                    engineParamDetailPojo.setLastUpdateDate(Timestamp.valueOf(LocalDateTime.now()));
                    engineParamDetailPojo.setCreationDate(Timestamp.valueOf(LocalDateTime.now()));
                    engineParamDetailPojo.setIsDistributedRes(Objects.equals(parameter.getParameterSource(), "数据平台手工录入") ? 0 : 2);
                    engineParamDetailPojo.setIsDistributedFilled(Objects.equals(parameter.getParameterSource(), "数据平台手工录入") ? 0 : 2);
                    engineParamDetailPojos.add(engineParamDetailPojo);
                }
            } else {
                for (ParameterPojo parameter : uniqueParameters) {
                    EngineParamDetailPojo engineParamDetailPojo = new EngineParamDetailPojo();
                    engineParamDetailPojo.setEngineModelId(modelPojo.getId());
                    engineParamDetailPojo.setParameterId(parameter.getId());
                    engineParamDetailPojo.setSubsystemName(parameter.getSubsystemName());
                    engineParamDetailPojo.setParameterType(parameter.getParameterType());
                    engineParamDetailPojo.setPartsName(parameter.getPartsName());
                    engineParamDetailPojo.setParameterName(parameter.getParameterName());
                    engineParamDetailPojo.setParameterSource("数据平台手工录入");
                    engineParamDetailPojo.setDepartment(parameter.getDepartment());
                    engineParamDetailPojo.setMajorVersion(VERSION_NUMBER);
                    engineParamDetailPojo.setVersionStatus(ParamValueVersionEnum.DRAFT.getCode());
                    engineParamDetailPojo.setCreatedBy(usersPojo.getId());
                    engineParamDetailPojo.setLastUpdatedBy("");
                    engineParamDetailPojo.setLastUpdateDate(Timestamp.valueOf(LocalDateTime.now()));
                    engineParamDetailPojo.setCreationDate(Timestamp.valueOf(LocalDateTime.now()));
                    engineParamDetailPojo.setIsDistributedRes(0);
                    engineParamDetailPojo.setIsDistributedFilled(0);
                    engineParamDetailPojos.add(engineParamDetailPojo);
                }
            }
        }
        businessDatabase.getBusinessDatabase().doBatchInsert(engineParamDetailPojos);
    }
}
