package com.yeejoin.amos.boot.module.hygf.biz.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yeejoin.amos.boot.biz.common.utils.DateUtils;
import com.yeejoin.amos.boot.biz.common.utils.ExcelUtils;
import com.yeejoin.amos.boot.module.hygf.api.dto.PowerStationTimeStatisticsBatchDto;
import com.yeejoin.amos.boot.module.hygf.api.dto.PowerStationTimeStatisticsDto;
import com.yeejoin.amos.boot.module.hygf.api.mapper.PeasantHouseholdMapper;
import com.yeejoin.amos.boot.module.hygf.api.util.ListUtils;
import com.yeejoin.amos.boot.module.hygf.biz.vo.PowerStationTimeStatisticsExcelVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;

import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class PowerStationStatisticsServiceImpl {
    @Autowired
    PeasantHouseholdMapper peasantHouseholdMapper;

    public Page<PowerStationTimeStatisticsDto> queryForPage(int current, int size, PowerStationTimeStatisticsDto powerStationTimeStatisticsDto) {
        PageHelper.startPage(current, size);
        List<PowerStationTimeStatisticsDto> list = peasantHouseholdMapper.queryForPageByPowerStationStatistics(powerStationTimeStatisticsDto);
        PageInfo<PowerStationTimeStatisticsDto> pages = new PageInfo(list);
        addPowerStationTime(pages.getList());
        Page<PowerStationTimeStatisticsDto> page = new Page<>();
        page.setCurrent(current);
        page.setTotal(pages.getTotal());
        page.setSize(size);
        page.setRecords(pages.getList());
        return page;
    }

    /**
     * 添加场站时间
     * @param statisticsDtos
     */
    private void addPowerStationTime(List<PowerStationTimeStatisticsDto> statisticsDtos) {
        if (CollectionUtil.isNotEmpty(statisticsDtos)) {
            List<Long> sequenceNbrList = new ArrayList<>();
//            for (PowerStationTimeStatisticsDto statisticsDto : statisticsDtos) {
//                sequenceNbrList.add(statisticsDto.getSequenceNbr());
//            }
            Map<Long, List<PowerStationTimeStatisticsDto>> kcMap = getKcTime(sequenceNbrList);
            Map<Long, List<PowerStationTimeStatisticsDto>> dzhtqyMap = getDzhtqyTime(sequenceNbrList);
            Map<Long, List<PowerStationTimeStatisticsDto>> sjMap = getSjTime(sequenceNbrList);
            Map<Long, List<PowerStationTimeStatisticsDto>> fhbhMap = getFhbhTime(sequenceNbrList);
            Map<Long, List<PowerStationTimeStatisticsDto>> sgMap = getSgTime(sequenceNbrList);
            Map<Long, List<PowerStationTimeStatisticsDto>> bwMap = getBwTime(sequenceNbrList);
            Map<Long, List<PowerStationTimeStatisticsDto>> ysMap = getYsTime(sequenceNbrList);
            Map<Long, List<PowerStationTimeStatisticsDto>> trMap = getTrTime(sequenceNbrList);
            for (PowerStationTimeStatisticsDto statisticsDto : statisticsDtos) {
                dealKcTime(statisticsDto, kcMap);
                dealDzhtqyTime(statisticsDto, dzhtqyMap);
                dealSjTime(statisticsDto, sjMap);
                dealFhbhTime(statisticsDto, fhbhMap);
                dealSgTime(statisticsDto, sgMap);
                dealBwTime(statisticsDto, bwMap);
                dealYsTime(statisticsDto, ysMap);
                dealTrTime(statisticsDto, trMap);
            }
        }
    }

    private void dealTrTime(PowerStationTimeStatisticsDto statisticsDto, Map<Long, List<PowerStationTimeStatisticsDto>> map) {
        List<PowerStationTimeStatisticsDto> time = map.get(statisticsDto.getSequenceNbr());
        if (CollectionUtil.isNotEmpty(time)) {
            statisticsDto.setTrCreateTime(time.get(0).getTrCreateTime());
            statisticsDto.setTrEndTime(time.get(0).getTrEndTime());
            statisticsDto.setTrStopTime(dealStopTime(time.get(0).getTrCreateTime(), time.get(0).getTrEndTime()));
        }
    }

    private Map<Long, List<PowerStationTimeStatisticsDto>> getTrTime(List<Long> sequenceNbrList) {
        List<PowerStationTimeStatisticsDto> statisticsDtos = new ArrayList<>();
        if (sequenceNbrList.size() < 1000) {
            statisticsDtos = peasantHouseholdMapper.getTrTime(sequenceNbrList);
        } else {
            List<List<Long>> lists = ListUtils.splitList(sequenceNbrList, 1000);
            for (List<Long> list : lists) {
                statisticsDtos.addAll(peasantHouseholdMapper.getTrTime(list));
            }
        }
        return statisticsDtos.stream().collect(Collectors.groupingBy(PowerStationTimeStatisticsDto::getSequenceNbr));
    }

    private Map<Long, List<PowerStationTimeStatisticsDto>> getYsTime(List<Long> sequenceNbrList) {
        List<PowerStationTimeStatisticsDto> statisticsDtos = new ArrayList<>();
        if (sequenceNbrList.size() < 1000) {
            statisticsDtos = peasantHouseholdMapper.getYsTime(sequenceNbrList);
        } else {
            List<List<Long>> lists = ListUtils.splitList(sequenceNbrList, 1000);
            for (List<Long> list : lists) {
                statisticsDtos.addAll(peasantHouseholdMapper.getYsTime(list));
            }
        }
        return statisticsDtos.stream().collect(Collectors.groupingBy(PowerStationTimeStatisticsDto::getSequenceNbr));
    }

    private Map<Long, List<PowerStationTimeStatisticsDto>> getBwTime(List<Long> sequenceNbrList) {
        List<PowerStationTimeStatisticsDto> statisticsDtos = new ArrayList<>();
        if (sequenceNbrList.size() < 1000) {
            statisticsDtos = peasantHouseholdMapper.getBwTime(sequenceNbrList);
        } else {
            List<List<Long>> lists = ListUtils.splitList(sequenceNbrList, 1000);
            for (List<Long> list : lists) {
                statisticsDtos.addAll(peasantHouseholdMapper.getBwTime(list));
            }
        }
        return statisticsDtos.stream().collect(Collectors.groupingBy(PowerStationTimeStatisticsDto::getSequenceNbr));
    }

    private Map<Long, List<PowerStationTimeStatisticsDto>> getSgTime(List<Long> sequenceNbrList) {
        List<PowerStationTimeStatisticsDto> statisticsDtos = new ArrayList<>();
        if (sequenceNbrList.size() < 1000) {
            statisticsDtos = peasantHouseholdMapper.getSgTime(sequenceNbrList);
        } else {
            List<List<Long>> lists = ListUtils.splitList(sequenceNbrList, 1000);
            for (List<Long> list : lists) {
                statisticsDtos.addAll(peasantHouseholdMapper.getSgTime(list));
            }
        }
        return statisticsDtos.stream().collect(Collectors.groupingBy(PowerStationTimeStatisticsDto::getSequenceNbr));
    }

    private Map<Long, List<PowerStationTimeStatisticsDto>> getFhbhTime(List<Long> sequenceNbrList) {
        List<PowerStationTimeStatisticsDto> statisticsDtos = new ArrayList<>();
        if (sequenceNbrList.size() < 1000) {
            statisticsDtos = peasantHouseholdMapper.getFhbhTime(sequenceNbrList);
        } else {
            List<List<Long>> lists = ListUtils.splitList(sequenceNbrList, 1000);
            for (List<Long> list : lists) {
                statisticsDtos.addAll(peasantHouseholdMapper.getFhbhTime(list));
            }
        }
        return statisticsDtos.stream().collect(Collectors.groupingBy(PowerStationTimeStatisticsDto::getSequenceNbr));
    }

    private Map<Long, List<PowerStationTimeStatisticsDto>> getSjTime(List<Long> sequenceNbrList) {
        List<PowerStationTimeStatisticsDto> statisticsDtos = new ArrayList<>();
        if (sequenceNbrList.size() < 1000) {
            statisticsDtos = peasantHouseholdMapper.getSjTime(sequenceNbrList);
        } else {
            List<List<Long>> lists = ListUtils.splitList(sequenceNbrList, 1000);
            for (List<Long> list : lists) {
                statisticsDtos.addAll(peasantHouseholdMapper.getSjTime(list));
            }
        }
        return statisticsDtos.stream().collect(Collectors.groupingBy(PowerStationTimeStatisticsDto::getSequenceNbr));
    }

    private Map<Long, List<PowerStationTimeStatisticsDto>> getDzhtqyTime(List<Long> sequenceNbrList) {
        List<PowerStationTimeStatisticsDto> statisticsDtos = new ArrayList<>();
        if (sequenceNbrList.size() < 1000) {
            statisticsDtos = peasantHouseholdMapper.getDzhtqyTime(sequenceNbrList);
        } else {
            List<List<Long>> lists = ListUtils.splitList(sequenceNbrList, 1000);
            for (List<Long> list : lists) {
                statisticsDtos.addAll(peasantHouseholdMapper.getDzhtqyTime(list));
            }
        }
        return statisticsDtos.stream().collect(Collectors.groupingBy(PowerStationTimeStatisticsDto::getSequenceNbr));
    }

    private Map<Long, List<PowerStationTimeStatisticsDto>> getKcTime(List<Long> sequenceNbrList) {
        List<PowerStationTimeStatisticsDto> statisticsDtos = new ArrayList<>();
        if (sequenceNbrList.size() < 1000) {
            statisticsDtos = peasantHouseholdMapper.getKcTime(sequenceNbrList);
        } else {
            List<List<Long>> lists = ListUtils.splitList(sequenceNbrList, 1000);
            for (List<Long> list : lists) {
                statisticsDtos.addAll(peasantHouseholdMapper.getKcTime(list));
            }
        }
        return statisticsDtos.stream().collect(Collectors.groupingBy(PowerStationTimeStatisticsDto::getSequenceNbr));
    }

    /**
     * 处理停留时间
     * @param startDate
     * @param endDate
     * @return
     */
    private String dealStopTime(Date startDate, Date endDate) {
        if (Objects.nonNull(startDate) && Objects.nonNull(endDate)) {
            // 计算时间差
            long diffInMillis = endDate.getTime() - startDate.getTime();

            // 将毫秒差转换为小时、分钟和秒
            long diffInSeconds = diffInMillis / 1000;
            // 计算天、小时、分钟和秒
            long days = diffInSeconds / 86400; // 1天 = 86400秒
            long hours = (diffInSeconds % 86400) / 3600;
            long minutes = (diffInSeconds % 3600) / 60;
            long seconds = diffInSeconds % 60;
            return days + "天" + hours + "小时" + minutes + "分" + seconds + "秒";
        }
        return null;
    }

    /**
     * 处理验收时间
     * @param statisticsDto
     * @param map
     */
    private void dealYsTime(PowerStationTimeStatisticsDto statisticsDto, Map<Long, List<PowerStationTimeStatisticsDto>> map) {
        List<PowerStationTimeStatisticsDto> time = map.get(statisticsDto.getSequenceNbr());
        if (CollectionUtil.isNotEmpty(time)) {
            statisticsDto.setYsCreateTime(time.get(0).getYsCreateTime());
            statisticsDto.setYsEndTime(time.get(0).getYsEndTime());
            statisticsDto.setYsStopTime(dealStopTime(time.get(0).getYsCreateTime(), time.get(0).getYsEndTime()));
        }
    }

    /**
     * 处理并网时间
     * @param statisticsDto
     * @param map
     */
    private void dealBwTime(PowerStationTimeStatisticsDto statisticsDto, Map<Long, List<PowerStationTimeStatisticsDto>> map) {
        List<PowerStationTimeStatisticsDto> time = map.get(statisticsDto.getSequenceNbr());
        if (CollectionUtil.isNotEmpty(time)) {
            statisticsDto.setBwCreateTime(time.get(0).getBwCreateTime());
            statisticsDto.setBwEndTime(time.get(0).getBwEndTime());
            statisticsDto.setBwStopTime(dealStopTime(time.get(0).getBwCreateTime(), time.get(0).getBwEndTime()));
        }
    }

    /**
     * 处理施工时间
     * @param statisticsDto
     * @param map
     */
    private void dealSgTime(PowerStationTimeStatisticsDto statisticsDto, Map<Long, List<PowerStationTimeStatisticsDto>> map) {
        List<PowerStationTimeStatisticsDto> time = map.get(statisticsDto.getSequenceNbr());
        if (CollectionUtil.isNotEmpty(time)) {
            statisticsDto.setSgCreateTime(time.get(0).getSgCreateTime());
            statisticsDto.setSgEndTime(time.get(0).getSgEndTime());
            statisticsDto.setSgStopTime(dealStopTime(time.get(0).getSgCreateTime(), time.get(0).getSgEndTime()));
        }
    }

    /**
     * 处理发货备货时间
     * @param statisticsDto
     * @param map
     */
    private void dealFhbhTime(PowerStationTimeStatisticsDto statisticsDto, Map<Long, List<PowerStationTimeStatisticsDto>> map) {
        List<PowerStationTimeStatisticsDto> time = map.get(statisticsDto.getSequenceNbr());
        if (CollectionUtil.isNotEmpty(time)) {
            statisticsDto.setFhbhCreateTime(time.get(0).getFhbhCreateTime());
            statisticsDto.setFhbhEndTime(time.get(0).getFhbhEndTime());
            statisticsDto.setFhbhStopTime(dealStopTime(time.get(0).getFhbhCreateTime(), time.get(0).getFhbhEndTime()));
        }
    }

    /**
     * 处理设计时间
     * @param statisticsDto
     * @param map
     */
    private void dealSjTime(PowerStationTimeStatisticsDto statisticsDto, Map<Long, List<PowerStationTimeStatisticsDto>> map) {
        List<PowerStationTimeStatisticsDto> time = map.get(statisticsDto.getSequenceNbr());
        if (CollectionUtil.isNotEmpty(time)) {
            statisticsDto.setSjCreateTime(time.get(0).getSjCreateTime());
            statisticsDto.setSjEndTime(time.get(0).getSjEndTime());
            statisticsDto.setSjStopTime(dealStopTime(time.get(0).getSjCreateTime(), time.get(0).getSjEndTime()));
        }
    }

    /**
     * 处理电子合同签约时间
     * @param statisticsDto
     * @param map
     */
    private void dealDzhtqyTime(PowerStationTimeStatisticsDto statisticsDto, Map<Long, List<PowerStationTimeStatisticsDto>> map) {
        List<PowerStationTimeStatisticsDto> time = map.get(statisticsDto.getSequenceNbr());
        if (CollectionUtil.isNotEmpty(time)) {
            statisticsDto.setDzhtqyCreateTime(time.get(0).getDzhtqyCreateTime());
            statisticsDto.setDzhtqyEndTime(time.get(0).getDzhtqyEndTime());
            statisticsDto.setDzhtqyStopTime(dealStopTime(time.get(0).getDzhtqyCreateTime(), time.get(0).getDzhtqyEndTime()));
        }
    }

    /**
     * 处理勘察时间
     * @param statisticsDto
     * @param map
     */
    private void dealKcTime(PowerStationTimeStatisticsDto statisticsDto, Map<Long, List<PowerStationTimeStatisticsDto>> map) {
        List<PowerStationTimeStatisticsDto> time = map.get(statisticsDto.getSequenceNbr());
        if (CollectionUtil.isNotEmpty(time)) {
            statisticsDto.setKcCreateTime(time.get(0).getKcCreateTime());
            statisticsDto.setKcEndTime(time.get(0).getKcEndTime());
            statisticsDto.setKcStopTime(dealStopTime(time.get(0).getKcCreateTime(), time.get(0).getKcEndTime()));
        }

    }

    public void exportPowerStationExcel(PowerStationTimeStatisticsBatchDto statisticsBatchDto, HttpServletResponse response) {
        List<PowerStationTimeStatisticsDto> powerStationTimeStatisticsDtoList = getAllDetail(statisticsBatchDto);
        if (CollectionUtil.isNotEmpty(powerStationTimeStatisticsDtoList)) {
            try {
                List<PowerStationTimeStatisticsExcelVO> dataList = new ArrayList<>();
                for (PowerStationTimeStatisticsDto statisticsDto : powerStationTimeStatisticsDtoList) {
                    PowerStationTimeStatisticsExcelVO excelVO = BeanUtil.copyProperties(statisticsDto, PowerStationTimeStatisticsExcelVO.class);
                    excelVO.setKcCreateTime(DateUtils.dateFormat(statisticsDto.getKcCreateTime(), DateUtils.DATE_TIME_PATTERN));
                    excelVO.setKcEndTime(DateUtils.dateFormat(statisticsDto.getKcEndTime(), DateUtils.DATE_TIME_PATTERN));
                    excelVO.setBwCreateTime(DateUtils.dateFormat(statisticsDto.getBwCreateTime(), DateUtils.DATE_TIME_PATTERN));
                    excelVO.setBwEndTime(DateUtils.dateFormat(statisticsDto.getBwEndTime(), DateUtils.DATE_TIME_PATTERN));
                    excelVO.setDzhtqyCreateTime(DateUtils.dateFormat(statisticsDto.getDzhtqyCreateTime(), DateUtils.DATE_TIME_PATTERN));
                    excelVO.setDzhtqyEndTime(DateUtils.dateFormat(statisticsDto.getDzhtqyEndTime(), DateUtils.DATE_TIME_PATTERN));
                    excelVO.setSgCreateTime(DateUtils.dateFormat(statisticsDto.getSgCreateTime(), DateUtils.DATE_TIME_PATTERN));
                    excelVO.setSgEndTime(DateUtils.dateFormat(statisticsDto.getSgEndTime(), DateUtils.DATE_TIME_PATTERN));
                    excelVO.setYsCreateTime(DateUtils.dateFormat(statisticsDto.getYsCreateTime(), DateUtils.DATE_TIME_PATTERN));
                    excelVO.setYsEndTime(DateUtils.dateFormat(statisticsDto.getYsEndTime(), DateUtils.DATE_TIME_PATTERN));
                    excelVO.setSjCreateTime(DateUtils.dateFormat(statisticsDto.getSjCreateTime(), DateUtils.DATE_TIME_PATTERN));
                    excelVO.setSjEndTime(DateUtils.dateFormat(statisticsDto.getSjEndTime(), DateUtils.DATE_TIME_PATTERN));
                    excelVO.setFhbhCreateTime(DateUtils.dateFormat(statisticsDto.getFhbhCreateTime(), DateUtils.DATE_TIME_PATTERN));
                    excelVO.setFhbhEndTime(DateUtils.dateFormat(statisticsDto.getFhbhEndTime(), DateUtils.DATE_TIME_PATTERN));
                    excelVO.setTrCreateTime(DateUtils.dateFormat(statisticsDto.getTrCreateTime(), DateUtils.DATE_TIME_PATTERN));
                    excelVO.setTrEndTime(DateUtils.dateFormat(statisticsDto.getTrEndTime(), DateUtils.DATE_TIME_PATTERN));
                    dataList.add(excelVO);
                }
                ExcelUtils.exportExcelDefaultGroundColor(dataList, null, "电站时间统计", PowerStationTimeStatisticsExcelVO.class, "电站时间统计" + DateUtils.dateFormat(new Date(), "YYYY-MM-dd-HH-mm") + ".xlsx", response);
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                throw new BadRequest("导出失败,失败原因[" + e.getMessage() + "]");
            }
        }
    }

    /**
     * 获取全部的详情
     * @param statisticsBatchDto
     * @return
     */
    private List<PowerStationTimeStatisticsDto> getAllDetail(PowerStationTimeStatisticsBatchDto statisticsBatchDto) {
        List<PowerStationTimeStatisticsDto> statisticsDtos = new ArrayList<>();
        List<String> sequenceNbrList = statisticsBatchDto.getSequenceNbrList();
        if (CollectionUtil.isNotEmpty(sequenceNbrList)) {
            if (sequenceNbrList.size() < 1000) {
                statisticsDtos = peasantHouseholdMapper.getPowerStationTimeDetail(sequenceNbrList);
            } else {
                List<List<String>> lists = ListUtils.splitList(sequenceNbrList, 1000);
                for (List<String> list : lists) {
                    statisticsDtos.addAll(peasantHouseholdMapper.getPowerStationTimeDetail(list));
                }
            }
        } else {
            statisticsDtos = peasantHouseholdMapper.getAllPowerStationTimeDetail(statisticsBatchDto.getFilters());
        }
        addPowerStationTime(statisticsDtos);
        return statisticsDtos;
    }

}
