package com.cf.imes.module.executor.service.order;

import cn.hutool.core.util.ObjectUtil;
import com.cf.imes.framework.common.enums.OrderStatisticsUnit;
import com.cf.imes.framework.organ.core.aop.OrganIgnore;
import com.cf.imes.module.executor.controller.admin.order.vo.order.OrderStatisticsAreaRespVO;
import com.cf.imes.module.executor.controller.admin.order.vo.order.OrderStatisticsIsLapseRespVO;
import com.cf.imes.module.executor.controller.admin.order.vo.order.OrderStatisticsReqVO;
import com.cf.imes.module.executor.dal.mysql.order.OrderStatisticsMapper;
import com.cf.imes.module.executor.dal.mysql.order.OrderSupStatisticsMapper;
import com.cf.imes.module.system.api.organ.OrganApi;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import jakarta.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

import static com.cf.imes.framework.common.util.time.StatisticsChangeUtils.*;

@Service
@Validated
public class OrderSupStatisticsServiceImpl implements OrderSupStatisticsService{
    @Resource
    private OrderStatisticsMapper orderStatisticsMapper;

    @Resource
    private OrderSupStatisticsMapper orderSupStatisticsMapper;

    @Resource
    private OrganApi organApi;

    @Override
    @OrganIgnore
    public Map<String, Integer> orderTotal() {
        Map<String, Integer> resultMap = new LinkedHashMap<>();
        // 生产单总数
        Integer total = orderStatisticsMapper.selectOrderCount();
        resultMap.put("total", total);

        // 日增长量
        Integer today = orderStatisticsMapper.selectOrderCountToday();
        resultMap.put("today", today);
        return resultMap;
    }

    @Override
    public Map<String, Double> plateAreaTotal() {
        Map<String, Double> resultMap = new LinkedHashMap<>();

        // 生产单板件平方数
        Double total = orderStatisticsMapper.selectOrderSquareProduce();
        resultMap.put("total", total);

        // 当日生产单板件平方数
        LocalDate date = LocalDate.now();
        LocalDateTime startTime = LocalDateTime.of(date, LocalTime.MIDNIGHT);
        LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);
        Double today = orderSupStatisticsMapper.selectOrderSquareProduceToday(startTime, endTime);
        resultMap.put("today", today);

        return resultMap;
    }

    @Override
    @OrganIgnore
    public Map<String, Object> orderSeparate(OrderStatisticsReqVO reqVO) {
        setOrderStatisticsReqVO(reqVO);

        Map<String, Object> resultMap = new LinkedHashMap<>();

        // 所有的日期集合
        List<String> dateList = getDateList(reqVO.getCreateTime(),reqVO.getUnit());

        // 生产单有效数量
        Map<String, List<OrderStatisticsIsLapseRespVO>> orderLapseRespMap = orderSupStatisticsMapper.selectOrderCountLapseByOrderDate(reqVO).stream()
                .sorted(Comparator.naturalOrder())
                .collect(Collectors.groupingBy(OrderStatisticsIsLapseRespVO::getDate, LinkedHashMap::new, Collectors.toList()));

        // 生产单无效数量
        Map<String, List<OrderStatisticsIsLapseRespVO>> orderNotLapseRespMap = orderSupStatisticsMapper.selectOrderCountNotLapseByOrderDate(reqVO).stream()
                .sorted(Comparator.naturalOrder())
                .collect(Collectors.groupingBy(OrderStatisticsIsLapseRespVO::getDate, LinkedHashMap::new, Collectors.toList()));

        // 遍历时间跨度列表，匹配数量存入数组，没有补0存入数组
        for (String dateStr : dateList) {
            int[] countArr = new int[2];
            // 生产单有效数量
            Integer orderNotLapseCount = Optional.ofNullable(orderNotLapseRespMap.get(dateStr))
                    .map(list -> list.stream().findFirst().orElse(new OrderStatisticsIsLapseRespVO()))
                    .map(OrderStatisticsIsLapseRespVO::getOrderCount)
                    .orElse(0);
            countArr[0] = orderNotLapseCount;


            // 生产单无效数量
            Integer orderLapseCount = Optional.ofNullable(orderLapseRespMap.get(dateStr))
                    .map(list -> list.stream().findFirst().orElse(new OrderStatisticsIsLapseRespVO()))
                    .map(OrderStatisticsIsLapseRespVO::getOrderCount)
                    .orElse(0);
            countArr[1] = orderLapseCount;

            resultMap.put(generateDateRangeAxis(dateStr, reqVO.getUnit()), countArr);
        }

        return resultMap;
    }

    @Override
    @OrganIgnore
    public Map<String, Object> plateAreaSeparate(OrderStatisticsReqVO reqVO) {
        setOrderStatisticsReqVO(reqVO);

        Map<String, Object> resultMap = new LinkedHashMap<>();

        // 所有的日期集合
        List<String> dateList = getDateList(reqVO.getCreateTime(),reqVO.getUnit());

        // 生产单有效板件平方数量
        Map<String, List<OrderStatisticsAreaRespVO>> orderLapseRespMap = orderSupStatisticsMapper.selectPlateAreaNotLapseByOrderDate(reqVO).stream()
                .sorted(Comparator.naturalOrder())
                .collect(Collectors.groupingBy(OrderStatisticsAreaRespVO::getDate, LinkedHashMap::new, Collectors.toList()));

        // 生产单无效板件平方数量
        Map<String, List<OrderStatisticsAreaRespVO>> orderNotLapseRespMap = orderSupStatisticsMapper.selectPlateAreaLapseByOrderDate(reqVO).stream()
                .sorted(Comparator.naturalOrder())
                .collect(Collectors.groupingBy(OrderStatisticsAreaRespVO::getDate, LinkedHashMap::new, Collectors.toList()));

        // 遍历时间跨度列表，匹配数量存入数组，没有补0存入数组
        for (String dateStr : dateList) {
            BigDecimal[] countArr = new BigDecimal[2];
            // 生产单有效数量
            BigDecimal orderNotLapseCount = Optional.ofNullable(orderNotLapseRespMap.get(dateStr))
                    .map(list -> list.stream().findFirst().orElse(new OrderStatisticsAreaRespVO()))
                    .map(OrderStatisticsAreaRespVO::getAreaSum)
                    .orElse(BigDecimal.valueOf(0));
            countArr[0] = orderNotLapseCount;


            // 生产单无效数量
            BigDecimal orderLapseCount = Optional.ofNullable(orderLapseRespMap.get(dateStr))
                    .map(list -> list.stream().findFirst().orElse(new OrderStatisticsAreaRespVO()))
                    .map(OrderStatisticsAreaRespVO::getAreaSum)
                    .orElse(BigDecimal.valueOf(0));
            countArr[1] = orderLapseCount;

            resultMap.put(generateDateRangeAxis(dateStr, reqVO.getUnit()), countArr);
        }

        return resultMap;
    }

    private void setOrderStatisticsReqVO(OrderStatisticsReqVO reqVO){
        if (ObjectUtil.isNull(reqVO.getUnit())){
            reqVO.setUnit(OrderStatisticsUnit.DAY.getValue());
        }
        if (ObjectUtil.isNull(reqVO.getCreateTime())){
            reqVO.setCreateTime(new LocalDate[2]);
        }
        LocalDate[] time = reqVO.getCreateTime();
        reqVO.setCreateTime(new LocalDate[]{time[0], time[1]});
    }
}
