package com.zhyc.module.feed.service.impl;

import java.util.*;

import com.zhyc.common.annotation.DataScope;
import com.zhyc.module.feed.domain.SgFeedPlan;
import com.zhyc.module.feed.domain.SgFormulaManagement;
import com.zhyc.module.feed.service.ISgFeedPlanService;
import com.zhyc.module.feed.service.ISgFormulaManagementService;
import lombok.Getter;
import org.springframework.stereotype.Service;
import com.zhyc.module.feed.mapper.SgFeedListMapper;
import com.zhyc.module.feed.domain.SgFeedList;
import com.zhyc.module.feed.service.ISgFeedListService;

/**
 * 配料清单Service业务层处理
 *
 * @author HashMap
 * @date 2025-08-19
 */
@Service
public class SgFeedListServiceImpl implements ISgFeedListService {
    private final SgFeedListMapper sgFeedListMapper;
    private final ISgFormulaManagementService sgFormulaManagementService;
    private final ISgFeedPlanService sgFeedPlanService;
    @Getter
    private final static Map<String, SgFeedList> sgFeedListMap = new HashMap<>();

    public SgFeedListServiceImpl(SgFeedListMapper sgFeedListMapper, ISgFormulaManagementService sgFormulaManagementService, ISgFeedPlanService sgFeedPlanService) {
        this.sgFeedListMapper = sgFeedListMapper;
        this.sgFormulaManagementService = sgFormulaManagementService;
        this.sgFeedPlanService = sgFeedPlanService;
        // 构造时将数据库初始数据写入缓存
        List<SgFeedList> feedListsFromDataBase = this.selectSgFeedListList(new SgFeedList());
        for (SgFeedList sgFeedListItem : feedListsFromDataBase) {
            String key = sgFeedListItem.getFormulaId() + "_" + sgFeedListItem.getFormulaBatchId() + "_" + sgFeedListItem.getDeployDate();
            sgFeedListMap.put(key, sgFeedListItem);
        }
    }

    /**
     * 查询配料清单
     *
     * @param id 配料清单主键
     * @return 配料清单
     */
    @Override
    public SgFeedList selectSgFeedListById(Long id) {
        return sgFeedListMapper.selectSgFeedListById(id);
    }

    /**
     * 查询配料清单列表
     *
     * @param sgFeedList 配料清单
     * @return 配料清单
     */
    @Override
    @DataScope(deptAlias = "sg_feed_list_alias", userAlias = "sg_feed_list_alias")
    public List<SgFeedList> selectSgFeedListList(SgFeedList sgFeedList) {
        return sgFeedListMapper.selectSgFeedListList(sgFeedList);
    }

    /**
     * 新增配料清单
     *
     * @param sgFeedList 配料清单
     * @return 结果
     */
    @Override
    public int insertSgFeedList(SgFeedList sgFeedList) {
        return sgFeedListMapper.insertSgFeedList(sgFeedList);
    }

    /**
     * 修改配料清单
     *
     * @param sgFeedList 配料清单
     * @return 结果
     */
    @Override
    public int updateSgFeedList(SgFeedList sgFeedList) {
        return sgFeedListMapper.updateSgFeedList(sgFeedList);
    }

    /**
     * 批量删除配料清单
     *
     * @param ids 需要删除的配料清单主键
     * @return 结果
     */
    @Override
    public int deleteSgFeedListByIds(Long[] ids) {
        return sgFeedListMapper.deleteSgFeedListByIds(ids);
    }

    /**
     * 删除配料清单信息
     *
     * @param id 配料清单主键
     * @return 结果
     */
    @Override
    public int deleteSgFeedListById(Long id) {
        return sgFeedListMapper.deleteSgFeedListById(id);
    }

    public void SyncFeedList_old() {
        // 清空旧缓存
        sgFeedListMap.clear();
        // 获取配方管理和现有配料清单内容
        List<SgFormulaManagement> formulaManagementList = sgFormulaManagementService.selectSgFormulaManagementList(new SgFormulaManagement());
        List<SgFeedList> feedLists = this.selectSgFeedListList(new SgFeedList());
        // 将最新查询的配料清单加入缓存
        for (SgFeedList sgFeedList : feedLists) {
            sgFeedListMap.put(sgFeedList.getFormulaId() + "_" + sgFeedList.getFormulaBatchId(), sgFeedList);
        }
        // 与新的配方管理列表同步 - 如果配料清单没有对应数据则加入
        for (SgFormulaManagement sgFormulaManagement : formulaManagementList) {
            // 匹配 但忽略模板配方
            if (sgFormulaManagement.getFormulaId() != null && sgFormulaManagement.getBatchId() != null && !sgFormulaManagement.getBatchId().equals("0")) {
                // 查询当前配方管理项是否存在现有配料计划中 (不论是否存在都要设置,因为缓存被清空,存在则更新,不存在则插入)
                boolean isExist = sgFeedListMap.containsKey(sgFormulaManagement.getFormulaId() + "_" + sgFormulaManagement.getBatchId());
                // 标志位 : 如果当前配方不在饲喂计划中则不生成配量清单
                boolean isPlan = true;
                // 设置缓存对象具体值
                SgFeedList sgFeedList = new SgFeedList();
                sgFeedList.setFormulaId(sgFormulaManagement.getFormulaId());
                sgFeedList.setFormulaBatchId(sgFormulaManagement.getBatchId());
                sgFeedList.setFormulaList(sgFormulaManagement.getSgFormulaList());
                sgFeedList.setRootFormula(sgFormulaManagement);


                // 从饲喂计划列表中查出对应值(饲喂量需要计划中的比例计算)
                SgFeedPlan rootPlanQuery = new SgFeedPlan();
                rootPlanQuery.setFormulaId(sgFormulaManagement.getFormulaId());
                rootPlanQuery.setBatchId(sgFormulaManagement.getBatchId());
                List<SgFeedPlan> sgFeedPlans = sgFeedPlanService.selectSgFeedPlanList(rootPlanQuery);
                // 为空则标识当前配方不在饲喂计划中 && 不在缓存中设置
                if (sgFeedPlans.isEmpty()) {
                    isPlan = false;
                } else {
                    // rootPlan中存储的是该配方批号的总量
                    SgFeedPlan rootPlan = computePlanTotal(sgFeedPlans);

                    // 将计划实体对象设置到配料清单中
                    sgFeedList.setRootPlan(rootPlan);

                    // 完整的配料清单对象加入缓存
                    sgFeedListMap.put(sgFormulaManagement.getFormulaId() + "_" + sgFormulaManagement.getBatchId(), sgFeedList);
                }

                // 不存在则插入
                if (!isExist && isPlan) {
                    this.insertSgFeedList(sgFeedList);
                }
            }
        }
    }

    public void SyncFeedList() {
        HashMap<String, SgFeedList> cacheTemp = new HashMap<>(sgFeedListMap);
        // 清空旧缓存
        sgFeedListMap.clear();
        List<SgFeedPlan> sgFeedPlans = sgFeedPlanService.selectSgFeedPlanList(new SgFeedPlan());
        List<List<SgFeedPlan>> planGroups = new ArrayList<>();
        List<SgFeedPlan> currentFeedPlan = new ArrayList<>();
        if (!sgFeedPlans.isEmpty()) {
            String currentFormulaId = sgFeedPlans.get(0).getFormulaId();
            String currentBatchId = sgFeedPlans.get(0).getBatchId();
            Date currentDate = sgFeedPlans.get(0).getPlanDate();
            // 对饲喂计划进行分组
            for (SgFeedPlan sgFeedPlan : sgFeedPlans) {
                if (sgFeedPlan.getBatchId() != null && !sgFeedPlan.getBatchId().equals("0")) {
                    if (sgFeedPlan.getFormulaId().equals(currentFormulaId) && sgFeedPlan.getBatchId().equals(currentBatchId) && sgFeedPlan.getPlanDate().equals(currentDate)) {
                        currentFeedPlan.add(sgFeedPlan);
                    } else {
                        currentDate = sgFeedPlan.getPlanDate();
                        currentBatchId = sgFeedPlan.getBatchId();
                        currentFormulaId = sgFeedPlan.getFormulaId();
                        planGroups.add(currentFeedPlan);
                        currentFeedPlan = new ArrayList<>();
                        // 立即插入否则会丢失该元素
                        currentFeedPlan.add(sgFeedPlan);
                    }
                }
            }
            // 插入最后一个列表 - 否则该列表会丢失
            planGroups.add(currentFeedPlan);
            // 注册数据 - 每一个List为一个清单
            for (List<SgFeedPlan> sgFeedPlanList : planGroups) {
                SgFeedList sgFeedList = new SgFeedList();
                // 计算饲喂总和
                SgFeedPlan rootPlan = computePlanTotal(sgFeedPlanList);
                sgFeedList.setRootPlan(rootPlan);
                sgFeedList.setPlanList(sgFeedPlanList);
                // 写入信息
                sgFeedList.setFormulaId(sgFeedPlanList.get(0).getFormulaId());
                sgFeedList.setFormulaBatchId(sgFeedPlanList.get(0).getBatchId());
                sgFeedList.setDeployDate(sgFeedPlanList.get(0).getPlanDate());
                // 写入配方管理信息
                SgFormulaManagement formulaManagementQuery = new SgFormulaManagement();
                formulaManagementQuery.setFormulaId(sgFeedList.getFormulaId());
                formulaManagementQuery.setBatchId(sgFeedList.getFormulaBatchId());
                List<SgFormulaManagement> formulaManagements = sgFormulaManagementService.selectSgFormulaManagementList(formulaManagementQuery);
                if (!formulaManagements.isEmpty()) {
                    sgFeedList.setRootFormula(formulaManagements.get(0));
                    sgFeedList.setFormulaList(formulaManagements.get(0).getSgFormulaList());
                }
                String cacheKey = sgFeedList.getFormulaId() + "_" + sgFeedList.getFormulaBatchId() + "_" + sgFeedList.getDeployDate();
                // 从就缓存中查找，如果存在则更新可修改的值
                if (cacheTemp.containsKey(cacheKey)) {
                    SgFeedList cacheItem = cacheTemp.get(cacheKey);
                    sgFeedList.setZookeeper(cacheItem.getZookeeper());
                }
                sgFeedListMap.put(cacheKey, sgFeedList);
            }

            List<SgFeedList> toDataBase = new ArrayList<>(sgFeedListMap.values());
            // 清空再写入
            this.sgFeedListMapper.deleteAll();
            // 处理结果写入数据库
            for (SgFeedList recordItem : toDataBase) {
                this.insertSgFeedList(recordItem);
            }
        }
    }

    /**
     * 计算某个配方某个批次的总和值
     *
     * @param sgFeedPlans 配方计划列表
     * @return 各个值总和
     */
    private static SgFeedPlan computePlanTotal(List<SgFeedPlan> sgFeedPlans) {
        SgFeedPlan rootPlan = new SgFeedPlan();
        if (!sgFeedPlans.isEmpty()) {
            int sheepCountTotal = 0;
            double sheepDailySize = 0.0;
            double planFeedMorningSize = 0.0;
            double planFeedNoonSize = 0.0;
            double planFeedAfternoonSize = 0.0;
            double planFeedTotalSize = 0.0;
            for (SgFeedPlan sgFeedPlan : sgFeedPlans) {
                sheepCountTotal += sgFeedPlan.getSheepCount();
                sheepDailySize += sgFeedPlan.getPlanDailySize();
                planFeedMorningSize += sgFeedPlan.getPlanMorningSize();
                planFeedNoonSize += sgFeedPlan.getPlanNoonSize();
                planFeedAfternoonSize += sgFeedPlan.getPlanAfternoonSize();
                planFeedTotalSize += sgFeedPlan.getPlanFeedTotal();
            }
            rootPlan.setFormulaId(sgFeedPlans.get(0).getFormulaId());
            rootPlan.setBatchId(sgFeedPlans.get(0).getBatchId());
            rootPlan.setSheepCount(sheepCountTotal);
            rootPlan.setPlanDailySize(sheepDailySize);
            rootPlan.setPlanMorningSize(planFeedMorningSize);
            rootPlan.setPlanNoonSize(planFeedNoonSize);
            rootPlan.setPlanAfternoonSize(planFeedAfternoonSize);
            rootPlan.setPlanFeedTotal(planFeedTotalSize);

            // 设置计划日期
            rootPlan.setPlanDate(sgFeedPlans.get(0).getPlanDate());
        }
        return rootPlan;
    }
}
