package com.sw.mes.kanban.service.impl;


import cn.hutool.core.collection.CollectionUtil;
import com.sw.mes.core.base.BaseServiceImpl;
import com.sw.mes.core.exception.BusinessException;
import com.sw.mes.core.utils.DateUtil;
import com.sw.mes.issue.entity.YbIssueRecord;
import com.sw.mes.kanban.dao.DailyProductionRecordDao;
import com.sw.mes.kanban.dto.TotalProductionDto;
import com.sw.mes.kanban.entity.DailyProductionRecord;
import com.sw.mes.kanban.service.DailyProductionRecordService;
import com.sw.mes.sap.reconciliation.sap.dao.SAPNativeSQL;
import com.sw.mes.utils.StringUtils;
import com.sw.mes.yb.production.entity.ProductionCircleRecipeDetail;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;


/**
* @Author
* @Description：
* @Date: Create in
* @Modified By:
*/
@Service
@Transactional
public class DailyProductionRecordServiceImpl extends BaseServiceImpl<DailyProductionRecord> implements DailyProductionRecordService {
    DailyProductionRecordDao dao;
	@Autowired
    public void setDao(DailyProductionRecordDao dao) {
        super.setBaseDao(dao);
        this.dao=dao;
    }


    public static final SimpleDateFormat shortSdf = new SimpleDateFormat("yyyy-MM-dd", Locale.CHINA);
    public static final SimpleDateFormat longSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA);

    @Autowired
    private SAPNativeSQL sapNativeSQL;



    @Override
    @XxlJob("runDailyProductionRecord")
    public void runDailyProductionRecord(String startTime, String endTime) throws Exception {
        if(StringUtils.isBlank(startTime) || StringUtils.isBlank(endTime)){
            startTime  = DateUtil.getLastDay830();
            endTime = DateUtil.getCurrentDayStartTime8H29M();
        }

        //单晶
        DailyProductionRecord record1 =  new DailyProductionRecord();
        List<Map<String, Object>> listSAP1 =  sapNativeSQL.queryCrystalCutSAP(startTime,endTime);
        BigDecimal totalSap1 = new BigDecimal(0);
        for (Map<String, Object> map : listSAP1) {
            String matnr = (String) map.get("menge");
            BigDecimal weight = new BigDecimal(StringUtils.isEmpty(matnr) ? "0" : matnr);
            totalSap1 = totalSap1.add(weight);
        }
        record1.setCreateDate(new Date());
        Date date  = shortSdf.parse(startTime);
        record1.setDate(date);
        record1.setStartTime(longSdf.parse(startTime));
        record1.setEndTime(longSdf.parse(endTime));
        record1.setProduction(totalSap1);
        record1.setType(1);
        DailyProductionRecord oldRecord1 = dao.findOldRecord(1,date);
        if(null != oldRecord1){
            record1.setId(oldRecord1.getId());
        }
        this.saveOrUpdate(record1);

        //圆棒
        DailyProductionRecord record2 =  new DailyProductionRecord();
        List<Map<String, Object>> listSAP2 =  sapNativeSQL.cutInputSAP(startTime,endTime);
        BigDecimal totalSap2 = new BigDecimal(0);
        for (Map<String, Object> map : listSAP2) {
            String matnr = (String) map.get("menge");
            BigDecimal weight = new BigDecimal(StringUtils.isEmpty(matnr) ? "0" : matnr);
            totalSap2 = totalSap2.add(weight);
        }
        record2.setCreateDate(new Date());
        record2.setDate(date);
        record2.setStartTime(longSdf.parse(startTime));
        record2.setEndTime(longSdf.parse(endTime));
        record2.setProduction(totalSap2);
        record2.setType(2);
        DailyProductionRecord oldRecord2 = dao.findOldRecord(2,date);
        if(null != oldRecord2){
            record2.setId(oldRecord2.getId());
        }
        this.saveOrUpdate(record2);


        //方棒
        DailyProductionRecord record3 =  new DailyProductionRecord();
        List<Map<String, Object>> listSAP3 =  sapNativeSQL.kfInputSAP(startTime,endTime);
        BigDecimal totalSap3 = new BigDecimal(0);
        for (Map<String, Object> map : listSAP3) {
            String matnr = (String) map.get("menge");
            BigDecimal weight = new BigDecimal(StringUtils.isEmpty(matnr) ? "0" : matnr);
            totalSap3 = totalSap3.add(weight);
        }
        record3.setCreateDate(new Date());
        record3.setDate(date);
        record3.setStartTime(longSdf.parse(startTime));
        record3.setEndTime(longSdf.parse(endTime));
        record3.setProduction(totalSap3);
        record3.setType(3);
        DailyProductionRecord oldRecord3 = dao.findOldRecord(3,date);
        if(null != oldRecord3){
            record3.setId(oldRecord3.getId());
        }
        this.saveOrUpdate(record3);


    }

    @Override
    public List<TotalProductionDto> findProductionByTime(String startTime, String endTime) {
        List<TotalProductionDto> dtos = new ArrayList<>();

//       Map<String, Object> map1 =  dao.countByTypeAndTime(startTime,endTime,1);
        TotalProductionDto dto1 = new TotalProductionDto();
        dto1.setType(1);
        //单晶收货
        Map<String, Object> map1 =  dao.countDJByTime(startTime,endTime);
        if(null != map1 && null != map1.get("total")){
            BigDecimal total =  BigDecimal.valueOf(Double.parseDouble(map1.get("total").toString()));
            dto1.setProduction(total);
        }else{
            dto1.setProduction(BigDecimal.ZERO);
        }
        dtos.add(dto1);
        
//        Map<String, Object> map2 =  dao.countByTypeAndTime(startTime,endTime,2);
        TotalProductionDto dto2 = new TotalProductionDto();
        dto2.setType(2);
        //截断收货
        Map<String, Object> map2 =  dao.countJDByTime(startTime,endTime);
        if(null != map2 && null != map2.get("total")){
            BigDecimal total =  BigDecimal.valueOf(Double.parseDouble(map2.get("total").toString()));
            dto2.setProduction(total);
        }else{
            dto2.setProduction(BigDecimal.ZERO);
        }
        dtos.add(dto2);

//        Map<String, Object> map3 =  dao.countByTypeAndTime(startTime,endTime,3);
        TotalProductionDto dto3 = new TotalProductionDto();
        dto3.setType(3);
        //刀剖收货
        Map<String, Object> map3 =  dao.countDPByTime(startTime,endTime);
        if(null != map3 && null != map3.get("total")){
            BigDecimal total =  BigDecimal.valueOf(Double.parseDouble(map3.get("total").toString()));
            dto3.setProduction(total);
        }else{
            dto3.setProduction(BigDecimal.ZERO);
        }
        dtos.add(dto3);

        return dtos;
    }

    @Override
    public Map<String,List<Map>> findDaysProductionByTime(String startTime,String endTime) {
        if(StringUtils.isBlank(startTime)  || StringUtils.isBlank(endTime)){
            throw new BusinessException("传入时间为空！");
        }
        List<Map<String,Object>> records = dao.findDaysByTypeAndTime(startTime,endTime);
        Map<String,List<Map>> maps = new LinkedHashMap<>();
        if(CollectionUtil.isNotEmpty(records)){
            maps = records.stream().collect(Collectors.groupingBy(map->map.get("date").toString()));
        }
        Map<String, List<Map>> sortedMap = maps.entrySet().stream()
                .sorted(Map.Entry.comparingByKey())
                .collect(Collectors.toMap(
                        Map.Entry::getKey,
                        Map.Entry::getValue,
                        (oldValue, newValue) -> oldValue, LinkedHashMap::new));


//        List<DailyProductionRecord> records =  dao.findByTypeAndTime(startTime,endTime);
//        Map<Date,List<DailyProductionRecord>> maps = new LinkedHashMap<>();
//        if(CollectionUtil.isNotEmpty(records)){
//             maps = records.stream().collect(Collectors.groupingBy(DailyProductionRecord::getDate));
//        }
//        Map<Date, List<DailyProductionRecord>> sortedMap = maps.entrySet().stream()
//                .sorted(Map.Entry.comparingByKey())
//                .collect(Collectors.toMap(
//                        Map.Entry::getKey,
//                        Map.Entry::getValue,
//                        (oldValue, newValue) -> oldValue, LinkedHashMap::new));

        return sortedMap;
    }

    @Override
    public void runBatchDailyProductionRecord(String startTime, String endTime) throws Exception {
        List<String> timeIntervals = splitTimeIntoDailyIntervals(startTime, endTime);
        for(String date : timeIntervals){
            String[] s = date.split("to");
            String startTime1 = s[0];
            String endTime1 = s[1];
            this.runDailyProductionRecord(startTime1,endTime1);
        }


    }

//    public static void main(String[] args) {
//        List<String> timeIntervals = splitTimeIntoDailyIntervals("2024-04-01 08:29:00", "2024-04-20 08:29:59");
//        for(String date : timeIntervals){
//            String[] s = date.split("to");
//            System.out.println(s[0] + "到"  +s[1]);
//        }
//
//    }


    private  static List<String> splitTimeIntoDailyIntervals(String start, String end) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime startTime = LocalDateTime.parse(start, formatter);
        LocalDateTime endTime = LocalDateTime.parse(end, formatter);

        List<String> intervals = new ArrayList<>();

        // 设置每天的开始时间为早上8:30
        LocalTime dayStartTime = LocalTime.of(8, 30);
        // 设置每天的结束时间为早上8:29:59
//        LocalTime dayEndTime = LocalTime.of(8, 29, 59);

        LocalDateTime currentStart = startTime.toLocalDate().atTime(dayStartTime);
        if (startTime.toLocalTime().isAfter(dayStartTime)) {
            currentStart = currentStart.plusDays(1);
        }

        LocalDateTime currentEnd = currentStart.plusDays(1).withNano(0).withSecond(59).withMinute(29).withHour(8);

        while (currentEnd.isBefore(endTime) || currentEnd.isEqual(endTime)) {
            intervals.add(currentStart.format(formatter) + "to" + currentEnd.format(formatter));
            currentStart = currentStart.plusDays(1);
            currentEnd = currentEnd.plusDays(1);
        }

        return intervals;
    }


}
