package cn.estsh.i3plus.ext.mes.apiservice.serviceimpl.busi.bu3;

import cn.estsh.i3plus.ext.mes.api.busi.bu3.ISxTrendAnalysisService;
import cn.estsh.i3plus.ext.mes.apiservice.dao.bu3.ISxTrendAnalysisDao;
import cn.estsh.i3plus.ext.mes.apiservice.util.SxDateRangeUtils;
import cn.estsh.i3plus.ext.mes.pojo.bean.*;
import cn.estsh.i3plus.ext.mes.pojo.model.bu3.SxEquipModel;
import cn.estsh.i3plus.ext.mes.pojo.model.bu3.SxTrendAnalysisModel;
import cn.estsh.i3plus.ext.mes.pojo.repository.MesEquipmentCheckRepository;
import cn.estsh.i3plus.ext.mes.pojo.repository.MesProcessQManageRepository;
import cn.estsh.i3plus.ext.mes.pojo.repository.MesQManageTaskDetailRepository;
import cn.estsh.i3plus.ext.mes.pojo.util.MesExtConstWords;
import cn.estsh.i3plus.ext.mes.pojo.util.MesExtEnumUtil;
import cn.estsh.i3plus.pojo.base.bean.ListPager;
import cn.estsh.i3plus.pojo.base.common.Pager;
import cn.estsh.i3plus.pojo.base.common.PagerHelper;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @PROJECT_NAME: i3plus-mes-panasonic-dev
 * @DESCRIPTION:
 * @USER: xinwang.yi
 * @DATE: 2023-07-03 11:40
 */
@Service
public class SxTrendAnalysisService implements ISxTrendAnalysisService {

    @Autowired
    private ISxTrendAnalysisDao trendAnalysisDao;

    @Autowired
    private MesEquipmentCheckRepository equipmentCheckRepository;

    @Override
    public Map<String, Object> queryTrendAnalysis(SxTrendAnalysisModel model, Pager pager) {
        Map<String, Object> resultMap = new HashMap<>();
        //上限值
        List<Double> upLimitList = new ArrayList<>();
        //下限值
        List<Double> downLimitList = new ArrayList<>();
        //点检输入值
        List<Double> checkValueList = new ArrayList<>();
        //趋势分析图X轴坐标
        List<String> dateList = new ArrayList<>();

        List<String> dateRangeList = SxDateRangeUtils.getDateRange(model.getSpotCheckTimeStart().substring(0,10), model.getSpotCheckTimeEnd().substring(0,10), MesExtConstWords.DATE_FORMAT);

        //表格展示数据
        switch (MesExtEnumUtil.TREND_ANALYSIS.getByValue(model.getDataType())) {
            case Q_MANAGE: packChartDataAndTableDataByQManage(model, resultMap, dateRangeList, upLimitList, downLimitList, checkValueList, dateList, pager); break;
            case FIRST_ORDER: packChartDataAndTableDataByFirstOrder(model, resultMap, dateRangeList, upLimitList, downLimitList, checkValueList, dateList, pager); break;
            case EQUIP_CHECK: packChartDataAndTableDataByEquipCheck(model, resultMap, dateRangeList, upLimitList, downLimitList, checkValueList, dateList, pager); break;
        }

        packResultMap(resultMap, upLimitList, downLimitList, checkValueList, dateList);

        return resultMap;
    }

    @Override
    public ListPager queryManageProjectsByDataType(SxTrendAnalysisModel model, Pager pager) {
        List<String> projectsList = new ArrayList<>();
        switch (MesExtEnumUtil.TREND_ANALYSIS.getByValue(model.getDataType())) {
            case Q_MANAGE: pager = PagerHelper.getPager(pager, trendAnalysisDao.queryQManageProjectsListPagerCount(model.getManageProjects(), model.getProcessCode(), model.getPartNo(), model.getOrganizeCode()));
                projectsList = trendAnalysisDao.queryQManageProjectsListPager(model.getManageProjects(), model.getProcessCode(), model.getPartNo(), model.getOrganizeCode(), pager); break;
            case FIRST_ORDER: pager = PagerHelper.getPager(pager, trendAnalysisDao.queryFirstOrderCheckMessageListPagerCount(model.getManageProjects(), model.getProcessCode(), model.getPartNo(), model.getOrganizeCode()));
                projectsList = trendAnalysisDao.queryFirstOrderCheckMessageListPager(model.getManageProjects(), model.getProcessCode(), model.getPartNo(), model.getOrganizeCode(), pager); break;
            case EQUIP_CHECK: pager = PagerHelper.getPager(pager, trendAnalysisDao.queryEquipCheckProjectContentPagerCount(model.getManageProjects(), model.getWorkCenterCode(), model.getWorkCellCode(), model.getEquNo(), model.getOrganizeCode()));
                projectsList = trendAnalysisDao.queryEquipCheckProjectContentListPager(model.getManageProjects(), model.getWorkCenterCode(), model.getWorkCellCode(), model.getEquNo(), model.getOrganizeCode(), pager); break;
        }

        return new ListPager(projectsList, pager);
    }

    @Override
    public ListPager queryEquipByPager(String equNo, String equName, String organizeCode, Pager pager) {
        pager = PagerHelper.getPager(pager, trendAnalysisDao.queryEquipListPagerCount(equNo, equName, organizeCode).intValue());
        List<SxEquipModel> equipModelList = trendAnalysisDao.queryEquipListPager(equNo, equName, organizeCode, pager);
        return new ListPager(equipModelList, pager);
    }

    @Override
    public String queryEquipByProjectContent(String workCenterCode, String workCellCode, String projectContent, String organizeCode) {
        if(StringUtils.isEmpty(workCenterCode) || StringUtils.isEmpty(workCellCode) || StringUtils.isEmpty(projectContent)) return "";
        MesEquipmentCheck equipmentCheck = equipmentCheckRepository.getByProperty(
                new String[]{MesExtConstWords.WORK_CENTER_CODE, MesExtConstWords.WORK_CELL_CODE, MesExtConstWords.PROJECT_CONTENT, MesExtConstWords.ORGANIZE_CODE, MesExtConstWords.IS_VALID, MesExtConstWords.IS_DELETED},
                new Object[]{workCenterCode, workCellCode, projectContent, organizeCode,
                        CommonEnumUtil.IS_VAILD.VAILD.getValue(),
                        CommonEnumUtil.IS_DEAL.NO.getValue()});

        return Optional.ofNullable(equipmentCheck).isPresent() ? equipmentCheck.getEquNo() : "";
    }

    //@Override
    //public String queryManageProjectsByPartNoAndProcessCode(String partNo, String processCode, String organizeCode) {
    //    if(StringUtils.isEmpty(partNo) || StringUtils.isEmpty(processCode)) return "";
    //    MesQManageTaskDetail qManageTaskDetail = qManageTaskDetailRepository.getByProperty(
    //            new String[]{MesExtConstWords.PART_NO, MesExtConstWords.WORK_CELL_CODE, MesExtConstWords.ORGANIZE_CODE, MesExtConstWords.IS_VALID, MesExtConstWords.IS_DELETED},
    //            new Object[]{ workCellCode, processCode, organizeCode,
    //                    CommonEnumUtil.IS_VAILD.VAILD.getValue(),
    //                    CommonEnumUtil.IS_DEAL.NO.getValue()});
    //}

    //@Override
    //public ListPager queryFirstOrderCheckMessage(Integer dataType , String manageProjects, String organizeCode, Pager pager) {
    //    pager = PagerHelper.getPager(pager, trendAnalysisDao.queryFirstOrderCheckMessageListPagerCount(manageProjects, organizeCode));
    //    List<String> orderCheckMessageListPager = trendAnalysisDao.queryFirstOrderCheckMessageListPager(manageProjects, organizeCode, pager);
    //    return new ListPager(orderCheckMessageListPager, pager);
    //}

    private void packChartDataAndTableDataByQManage(SxTrendAnalysisModel model, Map<String, Object> resultMap, List<String> dateRangeList, List<Double> upLimitList, List<Double> downLimitList, List<Double> checkValueList, List<String> dateList, Pager pager) {
        List<MesQManageTaskDetail> qManageTaskDetailList = trendAnalysisDao.queryQManageTaskDetailList(model);

        Map<String, MesQManageTaskDetail> manageTaskDetailMap = qManageTaskDetailList.stream().collect(Collectors.toMap(o -> o.getSpotCheckTime().substring(0, 10), Function.identity(), BinaryOperator.maxBy(Comparator.comparing(MesQManageTaskDetail::getSpotCheckTime))));
        List<MesQManageTaskDetail> qManageTaskDetailShowList = new ArrayList<>();
        for (String date : dateRangeList) {
            
            Double upLimit = 0.0;
            Double downLimit = 0.0;
            Double checkResult = null;
            
            MesQManageTaskDetail mesQManageTaskDetail = manageTaskDetailMap.get(date);
            if(mesQManageTaskDetail != null) {
                upLimit = Double.parseDouble(mesQManageTaskDetail.getUpLimit());
                downLimit = Double.parseDouble(mesQManageTaskDetail.getDownLimit());
                checkResult = Double.parseDouble(mesQManageTaskDetail.getManualTightening());
                mesQManageTaskDetail.setSpotCheckDate(date);
                qManageTaskDetailShowList.add(mesQManageTaskDetail);
            }

            upLimitList.add(upLimit);
            downLimitList.add(downLimit);
            checkValueList.add(checkResult);
            dateList.add(Integer.parseInt(date.substring(8)) + "");
        }
        pager = PagerHelper.getPager(pager, qManageTaskDetailShowList.size());
        resultMap.put("table", new ListPager(qManageTaskDetailShowList.stream().skip((long) (pager.getCurrentPage() - 1) * pager.getPageSize()).limit(pager.getPageSize()).collect(Collectors.toList()), pager));
    }

    private void packChartDataAndTableDataByQManageTest(SxTrendAnalysisModel model, Map<String, Object> resultMap, List<String> dateRangeList, List<Double> upLimitList, List<Double> downLimitList, List<Double> checkValueList, List<String> dateList, Pager pager) {
        List<MesQManageTaskDetail> qManageTaskDetailList = trendAnalysisDao.queryQManageTaskDetailList(model);

        Map<String, MesQManageTaskDetail> manageTaskDetailMap = qManageTaskDetailList.stream().collect(Collectors.toMap(o -> o.getSpotCheckTime().substring(0, 10), Function.identity(), BinaryOperator.maxBy(Comparator.comparing(MesQManageTaskDetail::getSpotCheckTime))));
        List<MesQManageTaskDetail> qManageTaskDetailShowList = new ArrayList<>();
        for (String date : dateRangeList) {

            double upLimit = 0.0;
            double downLimit = 0.0;
            double checkResult = 0.0;

            MesQManageTaskDetail mesQManageTaskDetail = manageTaskDetailMap.get(date);
            if(mesQManageTaskDetail != null) {
                upLimit = Double.parseDouble(mesQManageTaskDetail.getUpLimit());
                downLimit = Double.parseDouble(mesQManageTaskDetail.getDownLimit());
                checkResult = Double.parseDouble(mesQManageTaskDetail.getManualTightening());
                mesQManageTaskDetail.setSpotCheckDate(mesQManageTaskDetail.getSpotCheckTime().substring(0,10));
                qManageTaskDetailShowList.add(mesQManageTaskDetail);
            }

            upLimitList.add(upLimit);
            downLimitList.add(downLimit);
            checkValueList.add(checkResult);
            dateList.add(Integer.parseInt(date.substring(8)) + "");
        }
        pager = PagerHelper.getPager(pager, qManageTaskDetailShowList.size());
        resultMap.put("table", new ListPager(qManageTaskDetailShowList.stream().skip((long) (pager.getCurrentPage() - 1) * pager.getPageSize()).limit(pager.getPageSize()).collect(Collectors.toList()), pager));
    }

    private void packChartDataAndTableDataByFirstOrder(SxTrendAnalysisModel model, Map<String, Object> resultMap, List<String> dateRangeList, List<Double> upLimitList, List<Double> downLimitList, List<Double> checkValueList, List<String> dateList, Pager pager) {
        List<MesFirstOrderDetail> qManageTaskDetailList = trendAnalysisDao.queryFirstOrderDetailList(model);

        Map<String, MesFirstOrderDetail> firstOrderDetailMap = qManageTaskDetailList.stream().filter(o -> !StringUtils.isEmpty(o.getUpLimit()) && !StringUtils.isEmpty(o.getDownLimit())).collect(Collectors.toMap(o -> o.getSpotCheckTime().substring(0, 10), Function.identity(), BinaryOperator.maxBy(Comparator.comparing(MesFirstOrderDetail::getSpotCheckTime))));
        List<MesFirstOrderDetail> firstOrderDetailShowList = new ArrayList<>();
        for (String date : dateRangeList) {
            Double upLimit = 0.0;
            Double downLimit = 0.0;
            Double checkResult = null;
            MesFirstOrderDetail firstOrderDetail = firstOrderDetailMap.get(date);
            if(firstOrderDetail != null) {
                upLimit = Double.parseDouble(firstOrderDetail.getUpLimit());
                downLimit = Double.parseDouble(firstOrderDetail.getDownLimit());
                checkResult = Double.parseDouble(firstOrderDetail.getResultValue());
                firstOrderDetail.setSpotCheckDate(date);
                firstOrderDetailShowList.add(firstOrderDetail);
            }

            upLimitList.add(upLimit);
            downLimitList.add(downLimit);
            checkValueList.add(checkResult);
            dateList.add(Integer.parseInt(date.substring(8)) + "");
        }
        pager = PagerHelper.getPager(pager, firstOrderDetailShowList.size());
        resultMap.put("table", new ListPager(firstOrderDetailShowList.stream().skip((long) (pager.getCurrentPage() - 1) * pager.getPageSize()).limit(pager.getPageSize()).collect(Collectors.toList()), pager) );
    }

    private void packChartDataAndTableDataByEquipCheck(SxTrendAnalysisModel model, Map<String, Object> resultMap, List<String> dateRangeList, List<Double> upLimitList, List<Double> downLimitList, List<Double> checkValueList, List<String> dateList, Pager pager) {
        List<MesEquipmentCheckDetail> equipmentCheckDetailList =  trendAnalysisDao.queryEquipmentCheckDetailList(model);
        Map<String, MesEquipmentCheckDetail> equipmentCheckDetailMap = equipmentCheckDetailList.stream().filter(o -> !StringUtils.isEmpty(o.getUpLimit()) && !StringUtils.isEmpty(o.getDownLimit())).collect(Collectors.toMap(o -> o.getSpotCheckTime().substring(0, 10), Function.identity(), BinaryOperator.maxBy(Comparator.comparing(MesEquipmentCheckDetail::getSpotCheckTime))));
        List<MesEquipmentCheckDetail> equipmentCheckDetailShowList = new ArrayList<>();
        for (String date : dateRangeList) {
            MesEquipmentCheckDetail equipmentCheckDetail = equipmentCheckDetailMap.get(date);

            Double upLimit = 0.0;
            Double downLimit = 0.0;
            Double checkResult = null;
            if(equipmentCheckDetail != null) {
                upLimit = Double.parseDouble(equipmentCheckDetail.getUpLimit());
                downLimit = Double.parseDouble(equipmentCheckDetail.getDownLimit());
                checkResult = Double.parseDouble(equipmentCheckDetail.getResultValue());
                equipmentCheckDetail.setSpotCheckDate(date);
                equipmentCheckDetailShowList.add(equipmentCheckDetail);
            }

            upLimitList.add(upLimit);
            downLimitList.add(downLimit);
            checkValueList.add(checkResult);
            dateList.add(Integer.parseInt(date.substring(8)) + "");
        }
        pager = PagerHelper.getPager(pager, equipmentCheckDetailShowList.size());
        resultMap.put("table", new ListPager(equipmentCheckDetailShowList.stream().skip((long) (pager.getCurrentPage() - 1) * pager.getPageSize()).limit(pager.getPageSize()).collect(Collectors.toList()), pager));
    }

    private void packResultMap(Map<String, Object> resultMap, List<Double> upLimitList, List<Double> downLimitList, List<Double> checkValueList, List<String> dateList) {
        resultMap.put("xList", dateList);
        resultMap.put("upLimit", fillLimitList(upLimitList));
        resultMap.put("downLimit", fillLimitList(downLimitList));
        resultMap.put("checkValueList", checkValueList);
    }

    /**
     * 为 0 的数据按照上一个大于0 的数字自动填充
     * @param limitList
     * @return
     */
    private static List<Double> fillLimitList(List<Double> limitList) {
        if (!CollectionUtils.isEmpty(limitList)) {
            Double lastFillValue = 0.0;
            List<Integer> zeroIndexList = new ArrayList<>();
            for (int index = 0; index < limitList.size(); index++) {
                Double limitValue = limitList.get(index);
                if (limitValue == 0.0) {
                    zeroIndexList.add(index);
                } else if(!CollectionUtils.isEmpty(zeroIndexList) && limitValue != 0.0) {
                    for (Integer zeroIndex : zeroIndexList) {
                        limitList.set(zeroIndex, lastFillValue != 0.0 ? lastFillValue : limitValue);
                    }
                    zeroIndexList.clear();
                    lastFillValue = limitValue;
                }
            }

            if (!CollectionUtils.isEmpty(zeroIndexList)) {
                for (Integer zeroIndex : zeroIndexList) {
                    limitList.set(zeroIndex, lastFillValue);
                }
            }
        }
        return limitList;
    }

    //@Override
    //public Map<String, Object> queryFirstOrderTrendAnalysis(SxTrendAnalysisModel model, Pager pager) {
    //    Map<String, Object> resultMap = new HashMap<>();
    //    DdlPackBean packBean = MesExtHqlPack.getTrendAnalysis(model);
    //
    //
    //    List<String> dateRangeList = SxDateRangeUtils.getDateRange(model.getSpotCheckTimeStart(), model.getSpotCheckTimeStart(), MesExtConstWords.DATE_FORMAT);
    //
    //    //上限值
    //    List<Double> upLimitList = new ArrayList<>();
    //    //下限值
    //    List<Double> downLimitList = new ArrayList<>();
    //    //点检输入值
    //    List<Double> checkValueList = new ArrayList<>();
    //    //趋势分析图X轴坐标
    //    List<String> dateList = new ArrayList<>();
    //    //表格展示数据
    //    //packChartDataAndTableDataByFirstOrder(pager, resultMap, firstOrderDetailMap, dateRangeList, upLimitList, downLimitList, checkValueList, dateList);
    //    packResultMap(resultMap, upLimitList, downLimitList, checkValueList, dateList);
    //
    //    return resultMap;
    //}

    //@Override
    //public Map<String, Object> queryEquipCheckTrendAnalysis(SxTrendAnalysisModel model, Pager pager) {
    //    Map<String, Object> resultMap = new HashMap<>();
    //    DdlPackBean packBean = MesExtHqlPack.getTrendAnalysis(model);
    //
    //
    //    List<String> dateRangeList = SxDateRangeUtils.getDateRange(model.getSpotCheckTimeStart(), model.getSpotCheckTimeStart(), MesExtConstWords.DATE_FORMAT);
    //    //上限值
    //    List<Double> upLimitList = new ArrayList<>();
    //    //下限值
    //    List<Double> downLimitList = new ArrayList<>();
    //    //点检输入值
    //    List<Double> checkValueList = new ArrayList<>();
    //    //趋势分析图X轴坐标
    //    List<String> dateList = new ArrayList<>();
    //    //表格展示数据
    //    //packChartDataAndTableDataByEquipCheck(pager, resultMap, packBean, dateRangeList, upLimitList, downLimitList, checkValueList, dateList);
    //
    //    packResultMap(resultMap, upLimitList, downLimitList, checkValueList, dateList);
    //
    //    return resultMap;
    //}
}
