package com.ruoyi.app.service.impl;

import com.ruoyi.app.DTO.*;
import com.ruoyi.app.domain.request.SearchTimeRangeParam;
import com.ruoyi.app.domain.request.TimeRangeParam;
import com.ruoyi.app.mapper.*;
import com.ruoyi.app.service.IDataStatisticsService;
import com.ruoyi.common.utils.NumberUtil;
import com.ruoyi.common.utils.TimeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;

/**
 * 数据分析Service业务层处理
 *
 * @author ruoyi
 * @date 2025-03-28
 */
@Service
public class DataStatisticsServiceImpl implements IDataStatisticsService {

    //时间类型
    public static final String ALL = "1"; //全部
    public static final String THISYEAR = "2"; //本年
    public static final String THISMONTH = "3"; //本月
    public static final String THISWEEK = "4"; //本周
    public static final String THISDAY = "5"; //本日
    public static final String RANGE = "6"; //范围

    //其他产品类型
    public static final String PORKHEAD = "猪头"; //猪头
    public static final String PORKRED = "红脏"; //红脏
    public static final String PORKWHITE = "白脏"; //白脏

    @Autowired
    private SupplierMapper supplierMapper;

    @Autowired
    private PurchaserMapper purchaserMapper;

    @Autowired
    private HarmlessTreatmentMapper harmlessTreatmentMapper;

    @Autowired
    private EntranceBatchMapper entranceBatchMapper;

    @Autowired
    private DistributeBatchMapper distributeBatchMapper;

    @Autowired
    private PorkSideProduceMapper porkSideProduceMapper;

    @Autowired
    private PorkOtherProduceMapper porkOtherProduceMapper;

    //处理时间
    private void setTimeRange(TimeRangeParam timeRangeParam) {
        String timeType = timeRangeParam.getTimeType();
        if(Objects.equals(timeType, ALL)){
            timeRangeParam.setStartTime(null);
            timeRangeParam.setEndTime(null);
        }else if(Objects.equals(timeType, THISYEAR)){
            Date[] range = TimeUtil.getLastYearRangeWithCurrentTime(true);
            timeRangeParam.setStartTime(range[0]);
            timeRangeParam.setEndTime(range[1]);
        }else if(Objects.equals(timeType, THISMONTH)){
            Date[] range = TimeUtil.getLastMonthRangeWithCurrentTime(true);
            timeRangeParam.setStartTime(range[0]);
            timeRangeParam.setEndTime(range[1]);
        }else if(Objects.equals(timeType, THISWEEK)){
            Date[] range = TimeUtil.getLastSevenDaysRangeWithCurrentTime(true);
            timeRangeParam.setStartTime(range[0]);
            timeRangeParam.setEndTime(range[1]);
        }else if(Objects.equals(timeType, THISDAY)){
            Date[] range = TimeUtil.getTodayRangeWithCurrentTime();
            timeRangeParam.setStartTime(range[0]);
            timeRangeParam.setEndTime(range[1]);
        }
    };

    /**
     * 查询生产数据指标
     *
     * @param timeRangeParam 时间条件
     * @return 指标
     */
    @Override
    public HashMap<String, Object> getProdIndicator(TimeRangeParam timeRangeParam){
        HashMap<String, Object> resp = new HashMap<>();
        setTimeRange(timeRangeParam);
//        //获取交易数量
//        Long entranceCounts = entranceBatchMapper.selectCountByTime(timeRangeParam);
        //获取交易数量
        Long distributeCounts = distributeBatchMapper.selectCountByTime(timeRangeParam);
        //获取供应商数量
        Long supplierCounts = supplierMapper.selectCountByTime(timeRangeParam);
        //获取肉商数量
        Long purchaserCounts = purchaserMapper.selectCountByTime(timeRangeParam);
        //获取计划屠宰数量
        Long entranceAmount = entranceBatchMapper.selectAmountByTime(timeRangeParam);
        //获取死淘及不合格
        HarmlessSumDTO harmlessSum = harmlessTreatmentMapper.selectHarmlessSumByTime(timeRangeParam);
        resp.put("distributeCounts", distributeCounts);
        resp.put("supplierCounts", supplierCounts);
        resp.put("purchaserCounts", purchaserCounts);
        resp.put("entranceAmount", entranceAmount);
        resp.put("entranceRealAmount", NumberUtil.getLongValue(entranceAmount) - NumberUtil.getLongValue(harmlessSum.getIllnessDeadAmountSum()) - NumberUtil.getLongValue(harmlessSum.getIllnessDiseaseAmountSum()));
        resp.put("unqualifiedWeight",harmlessSum.getUnqualifiedWeightSum());
        return  resp;
    }

    /**
     * 获取供应商供应数量前五排名
     *
     * @param timeRangeParam 时间条件
     * @return 供应商供应数量集合
     */
    @Override
    public List<SupplierAmountRankDTO> selectAmountRankByTime(TimeRangeParam timeRangeParam){
        setTimeRange(timeRangeParam);
        return supplierMapper.selectAmountRankByTime(timeRangeParam);
    }

    /**
     * 获取肉商接收数量前五排名
     *
     * @param timeRangeParam 时间条件
     * @return 肉商接收数量集合
     */
    @Override
    public List<PurchaserAmountRankDTO> selectSaleAmountRankByTime(TimeRangeParam timeRangeParam){
        setTimeRange(timeRangeParam);
        return purchaserMapper.selectAmountRankByTime(timeRangeParam);
    }

    /**
     * 根据时间范围获取不同产地供应商供应数量
     *
     * @param timeRangeParam 时间条件
     * @return 产地供应商供应数量集合
     */
    @Override
    public List<SupplierOriginAmountDTO> selectOriginAmountByTime(TimeRangeParam timeRangeParam){
        setTimeRange(timeRangeParam);
        List<SupplierOriginAmountDTO> res = supplierMapper.selectOriginAmountByTime(timeRangeParam);
        return res;
    }

    /**
     * 根据时间范围获取不同去向肉商销售数量
     *
     * @param timeRangeParam 时间条件
     * @return 去向肉商接收数量集合
     */
    @Override
    public List<PurchaserSaleAmountDTO> selectSaleAmountByTime(TimeRangeParam timeRangeParam){
        setTimeRange(timeRangeParam);
        return purchaserMapper.selectSaleAmountByTime(timeRangeParam);
    }

    /**
     * 根据时间范围获取入场无害化检验统计
     *
     * @param timeRangeParam 时间条件
     * @return 统计结果
     */
    @Override
    public HashMap<String, Object> selectHarmlessSumByTime(TimeRangeParam timeRangeParam){
        HashMap<String, Object> resp = new HashMap<>();
        setTimeRange(timeRangeParam);
        //获取死淘及不合格
        HarmlessSumDTO harmlessSum = harmlessTreatmentMapper.selectHarmlessSumByTime(timeRangeParam);
        long illnessDeadAmount = NumberUtil.getLongValue(harmlessSum.getIllnessDeadAmountSum());
        long illnessDiseaseAmount = NumberUtil.getLongValue(harmlessSum.getIllnessDiseaseAmountSum());
        long snapKillAmount = NumberUtil.getLongValue(harmlessSum.getSnapKillAmountSum());
        //获取准宰数量
        long entranceRealAmount = NumberUtil.getLongValue(entranceBatchMapper.selectAmountByTime(timeRangeParam))-
                illnessDeadAmount - illnessDiseaseAmount - snapKillAmount;

        resp.put("illnessDeadAmount", illnessDeadAmount);
        resp.put("illnessDiseaseAmount", illnessDiseaseAmount);
        resp.put("snapKillAmount", snapKillAmount);
        resp.put("entranceRealAmount", entranceRealAmount );
        return  resp;
    }

    /**
     * 根据获取指定时间范围内每日累计计划屠宰
     *
     * @param timeRangeParam 时间条件
     * @return 结果
     */
    @Override
    public List<TimeAndNumberDTO> selectEntranceAmountByTime(TimeRangeParam timeRangeParam){
        setTimeRange(timeRangeParam);
        if(Objects.equals(timeRangeParam.getTimeType(), ALL)){
            //全部，按年获取
            return entranceBatchMapper.selectAllYearAmountByTime(timeRangeParam);
        }else if(Objects.equals(timeRangeParam.getTimeType(), THISYEAR)){
            //近一年每月累计
            return entranceBatchMapper.selectYearAmountByTime(timeRangeParam);
        }else if(Objects.equals(timeRangeParam.getTimeType(), THISMONTH)){
            //全近三十天的每日累计
            return entranceBatchMapper.selectMonthAmountByTime(timeRangeParam);
        }else if(Objects.equals(timeRangeParam.getTimeType(), THISWEEK)){
            //近七天的每日累计
            return entranceBatchMapper.selectWeekAmountByTime(timeRangeParam);
        }else if(Objects.equals(timeRangeParam.getTimeType(), THISDAY)){
            //今天，每小时累计
            return entranceBatchMapper.selectTodayAmountByTime(timeRangeParam);
        }else {
            //时间范围
            return entranceBatchMapper.selectRangeAmountByTime(timeRangeParam);
        }
    }

    /**
     * 查询产出数据指标
     *
     * @param timeRangeParam 时间条件
     * @return 指标
     */
    @Override
    public HashMap<String, Object> getOutputIndicator(TimeRangeParam timeRangeParam){
        HashMap<String, Object> resp = new HashMap<>();
        setTimeRange(timeRangeParam);
        //获取交易数量
        Long distributeCounts = distributeBatchMapper.selectCountByTime(timeRangeParam);
        //获取屠宰数量
        Long distributeAmounts = distributeBatchMapper.selectAmountByTime(timeRangeParam);
        //获取平均白条重量
        BigDecimal avgPorkSideWeight = porkSideProduceMapper.selectAvgWeightByTime(timeRangeParam);
        SearchTimeRangeParam searchTimeRangeParam = new SearchTimeRangeParam();
        searchTimeRangeParam.setTimeType(timeRangeParam.getTimeType());
        searchTimeRangeParam.setStartTime(timeRangeParam.getStartTime());
        searchTimeRangeParam.setEndTime(timeRangeParam.getEndTime());
        //获取平均猪头重量
        searchTimeRangeParam.setKeyword(PORKHEAD);
        BigDecimal avgPorkHeadWeight = porkOtherProduceMapper.selectAvgWeightByTime(searchTimeRangeParam);
        //获取平均红脏重量
        searchTimeRangeParam.setKeyword(PORKRED);
        BigDecimal avgPorkRedWeight = porkOtherProduceMapper.selectAvgWeightByTime(searchTimeRangeParam);
        //获取平均白脏重量
        searchTimeRangeParam.setKeyword(PORKWHITE);
        BigDecimal avgPorkWhiteWeight = porkOtherProduceMapper.selectAvgWeightByTime(searchTimeRangeParam);

        resp.put("distributeCounts", distributeCounts);
        resp.put("distributeAmounts", distributeAmounts);
        resp.put("avgPorkSideWeight", avgPorkSideWeight);
        resp.put("avgPorkHeadWeight", avgPorkHeadWeight);
        resp.put("avgPorkRedWeight", avgPorkRedWeight);
        resp.put("avgPorkWhiteWeight",avgPorkWhiteWeight);
        return  resp;
    }

    /**
     * 根据获取指定时间范围内每日累计白条重量
     *
     * @param timeRangeParam 时间条件
     * @return 结果
     */
    @Override
    public List<TimeAndWeightDTO> selectSideWeightByTime(TimeRangeParam timeRangeParam){
        setTimeRange(timeRangeParam);
        if(Objects.equals(timeRangeParam.getTimeType(), ALL)){
            //全部，按年获取
            return porkSideProduceMapper.selectAllYearWeightByTime(timeRangeParam);
        }else if(Objects.equals(timeRangeParam.getTimeType(), THISYEAR)){
            //近一年每月累计
            return porkSideProduceMapper.selectYearWeightByTime(timeRangeParam);
        }else if(Objects.equals(timeRangeParam.getTimeType(), THISMONTH)){
            //全近三十天的每日累计
            return porkSideProduceMapper.selectMonthWeightByTime(timeRangeParam);
        }else if(Objects.equals(timeRangeParam.getTimeType(), THISWEEK)){
            //近七天的每日累计
            return porkSideProduceMapper.selectWeekWeightByTime(timeRangeParam);
        }else if(Objects.equals(timeRangeParam.getTimeType(), THISDAY)){
            //今天，每小时累计
            return porkSideProduceMapper.selectTodayWeightByTime(timeRangeParam);
        }else {
            //时间范围
            return porkSideProduceMapper.selectRangeWeightByTime(timeRangeParam);
        }
    }

    /**
     * 根据获取指定时间范围内每日累计其他产品重量
     *
     * @param searchTimeRangeParam 时间条件
     * @return 结果
     */
    @Override
    public List<TimeAndWeightDTO> selectOtherProductWeightByTime(SearchTimeRangeParam searchTimeRangeParam){
        setTimeRange(searchTimeRangeParam);
        if(Objects.equals(searchTimeRangeParam.getTimeType(), ALL)){
            //全部，按年获取
            return porkOtherProduceMapper.selectAllYearWeightByTime(searchTimeRangeParam);
        }else if(Objects.equals(searchTimeRangeParam.getTimeType(), THISYEAR)){
            //近一年每月累计
            return porkOtherProduceMapper.selectYearWeightByTime(searchTimeRangeParam);
        }else if(Objects.equals(searchTimeRangeParam.getTimeType(), THISMONTH)){
            //全近三十天的每日累计
            return porkOtherProduceMapper.selectMonthWeightByTime(searchTimeRangeParam);
        }else if(Objects.equals(searchTimeRangeParam.getTimeType(), THISWEEK)){
            //近七天的每日累计
            return porkOtherProduceMapper.selectWeekWeightByTime(searchTimeRangeParam);
        }else if(Objects.equals(searchTimeRangeParam.getTimeType(), THISDAY)){
            //今天，每小时累计
            return porkOtherProduceMapper.selectTodayWeightByTime(searchTimeRangeParam);
        }else {
            //时间范围
            return porkOtherProduceMapper.selectRangeWeightByTime(searchTimeRangeParam);
        }
    }

    /**
     * 获取今日昨日指标
     *
     * @return 指标
     */
    @Override
    public HashMap<String, Object> getLatelyIndicator(){
        HashMap<String, Object> resp = new HashMap<>();
        //获取今日订单数
        Long todayCounts = distributeBatchMapper.selectTodayCount();
        //获取昨日订单数
        Long yesterdayCounts = distributeBatchMapper.selectYesterdayCount();

        //获取今日屠宰数
        DailyEntranceAmountDTO todayAmountDTO = entranceBatchMapper.selectTodayAmount();
        //获取昨日屠宰数
        DailyEntranceAmountDTO yesterdayAmountDTO = entranceBatchMapper.selectYesterdayAmount();
        long todayAmount = 0;
        long yesterdayAmount = 0;
        if(todayAmountDTO != null){
            todayAmount = NumberUtil.getLongValue(todayAmountDTO.getEntranceAmountSum()) - NumberUtil.getLongValue(todayAmountDTO.getIllnessDeadAmountSum())
                    - NumberUtil.getLongValue(todayAmountDTO.getIllnessDiseaseAmountSum());
        }
        if(yesterdayAmountDTO != null){
            yesterdayAmount  = NumberUtil.getLongValue(yesterdayAmountDTO.getEntranceAmountSum()) - NumberUtil.getLongValue(yesterdayAmountDTO.getIllnessDeadAmountSum())
                    - NumberUtil.getLongValue(yesterdayAmountDTO.getIllnessDiseaseAmountSum());
        }
        TimeRangeParam timeRangeParam  = new TimeRangeParam();
        timeRangeParam.setTimeType(ALL);
        //获取累计分销订单数量
        Long distributeCounts = distributeBatchMapper.selectCountByTime(timeRangeParam);
        //获取计划屠宰数量
        Long entranceAmount = entranceBatchMapper.selectAmountByTime(timeRangeParam);
        //获取死淘及不合格
        HarmlessSumDTO harmlessSum = harmlessTreatmentMapper.selectHarmlessSumByTime(timeRangeParam);

        long entranceRealAmount = NumberUtil.getLongValue(entranceAmount) - NumberUtil.getLongValue(harmlessSum.getIllnessDeadAmountSum())
                - NumberUtil.getLongValue(harmlessSum.getIllnessDiseaseAmountSum());

        resp.put("distributeCounts", distributeCounts);
        resp.put("entranceRealAmount", entranceRealAmount);
        resp.put("todayCounts", todayCounts);
        resp.put("yesterdayCounts", yesterdayCounts);
        resp.put("todayAmount", todayAmount);
        resp.put("yesterdayAmount", yesterdayAmount);
        return  resp;
    }

    /**
     * 获取近七天每日入场订单量
     *
     * @return 指标
     */
    @Override
    public List<TimeAndNumberDTO>getWeekEntranceCount(){
        return entranceBatchMapper.selectWeekCountByTime();
    }

    /**
     * 获取近七天每日分销订单量
     *
     * @return 指标
     */
    @Override
    public List<TimeAndNumberDTO>getWeekDistributeCount(){
        return distributeBatchMapper.selectWeekCountByTime();
    }

    /**
     * 获取各部位重量对比情况
     *
     * @return 结果
     */
    @Override
    public HashMap<String,Object> getPorkPartWeight(){
        HashMap<String, Object> resp = new HashMap<>();
        SearchTimeRangeParam searchTimeRangeParam = new SearchTimeRangeParam();
        searchTimeRangeParam.setTimeType(THISWEEK);
        setTimeRange(searchTimeRangeParam);
        //白条近七天的每日累计
        List<TimeAndWeightDTO> sideWeight =  porkSideProduceMapper.selectWeekWeightByTime(searchTimeRangeParam);
        //猪头
        searchTimeRangeParam.setKeyword(PORKHEAD);
        List<TimeAndWeightDTO> headWeight =  porkOtherProduceMapper.selectWeekWeightByTime(searchTimeRangeParam);
        //红脏
        searchTimeRangeParam.setKeyword(PORKRED);
        List<TimeAndWeightDTO> redWeight =  porkOtherProduceMapper.selectWeekWeightByTime(searchTimeRangeParam);
        //白脏
        searchTimeRangeParam.setKeyword(PORKWHITE);
        List<TimeAndWeightDTO> whiteWeight =  porkOtherProduceMapper.selectWeekWeightByTime(searchTimeRangeParam);

        resp.put("sideWeight", sideWeight);
        resp.put("headWeight", headWeight);
        resp.put("redWeight", redWeight);
        resp.put("whiteWeight", whiteWeight);
        return  resp;
    }

    /**
     * 获取产地/去向对比情况
     *
     * @return 结果
     */
    @Override
    public HashMap<String,Object> getPlaceAmount(){
        HashMap<String, Object> resp = new HashMap<>();
        TimeRangeParam timeRangeParam = new TimeRangeParam();
        timeRangeParam.setTimeType(THISWEEK);
        setTimeRange(timeRangeParam);
        List<PurchaserSaleAmountDTO>toAmount =  purchaserMapper.selectSaleAmountByTime(timeRangeParam);
        List<SupplierOriginAmountDTO>fromAmount =  supplierMapper.selectOriginAmountByTime(timeRangeParam);
        resp.put("fromAmount", fromAmount);
        resp.put("toAmount", toAmount);
        return  resp;
    }
}
