package com.ruoyi.app.service.impl;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.beust.ah.A;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.JsonArray;
import com.ruoyi.app.DTO.EntranceReportDTO;
import com.ruoyi.app.DTO.PurchaserProduceTotalDTO;
import com.ruoyi.app.DTO.SlaughterReportDTO;
import com.ruoyi.common.model.AvailableField;
import com.ruoyi.app.model.request.*;
import com.ruoyi.app.mapper.EntranceBatchMapper;
import com.ruoyi.app.mapper.PorkSideProduceRecordMapper;
import com.ruoyi.app.mapper.SlaughterBatchMapper;
import com.ruoyi.app.model.response.*;
import com.ruoyi.app.service.IDataReportService;
import com.ruoyi.common.model.ExportField;
import org.apache.commons.beanutils.BeanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 数据报表Service业务层处理
 *
 * @author ruoyi
 * @date 2025-03-31
 */
@Service
public class DataReportServiceImpl implements IDataReportService {

    @Autowired
    private EntranceBatchMapper entranceBatchMapper;
    @Autowired
    private SlaughterBatchMapper slaughterBatchMapper;

    @Autowired
    private PorkSideProduceRecordMapper porkSideProduceRecordMapper;


    private static final Logger log = LoggerFactory.getLogger(DataReportServiceImpl.class);

    /**
     * 入场统计报表
     * @return 结果
     */
    @Override
    public List<EntranceReportDTO> selectEntranceReport(ReqEntranceReport reqEntranceReport){
        return entranceBatchMapper.selectEntranceReport(reqEntranceReport);
    }

    /**
     * 生产统计报表
     * @return 结果
     */
    @Override
    public List<SlaughterReportDTO> selectSlaughterReport(ReqSlaughterReport reqSlaughterReport){
        return slaughterBatchMapper.selectSlaughterReport(reqSlaughterReport);
    }

    /**
     * 称重统计报表
     * @return 结果
     */
    @Override
    public List<PurchaserProduceTotalDTO> selectPurchaserProduceTotal(ReqGetPorkSideProduceRecord req){
        return porkSideProduceRecordMapper.selectPurchaserProduceTotal(req);
    }

    /**
     * 生猪屠宰情况日汇总表  2025-10-09
     *
     * @param req 查询条件
     * @return 集合
     */
    @Override
    public List<GetDailySlaughterReportResp> selectDailySlaughterReport(GetDailySlaughterReportReq req){
        List<GetDailySlaughterReportResp> resultList = slaughterBatchMapper.selectDailySlaughterReport(req);
        for (GetDailySlaughterReportResp result:resultList){
            result.setTuzaiAmount(result.getAmount() - result.getIllnessDeadAmount() - result.getIllnessDiseaseAmount() - result.getRoadDealAmount() - result.getSnapKillAmount() - result.getDealAmount());
            result.setAllTuzaiAmount(result.getTuzaiAmount() + result.getSnapKillAmount());
            result.setDongAmountStr(result.getDongAmount() + "头");
            result.setWeightStr(result.getWeight() + "kg");
        }
        return resultList;
    }

    /**
     * 生猪入场查验情况表  2025-10-15
     *
     * @param req 查询条件
     * @return 集合
     */
    @Override
    public List<GetDailyEntranceReportResp> selectDailyEntranceReport(GetDailyEntranceReportReq req){
        List<GetDailyEntranceReportResp> resultList = slaughterBatchMapper.selectDailyEntranceReport(req);
        for (GetDailyEntranceReportResp result:resultList){
            result.setQualifiedAmount(result.getAmount() - result.getIllnessDeadAmount() - result.getIllnessDiseaseAmount() - result.getRoadDealAmount());
            result.setTuzaiAmount(result.getAmount() + result.getRoadDealAmount());
            if ("1".equals(result.getOriginPlace())) {
                result.setOriginPlace("本市");
            } else if ("2".equals(result.getOriginPlace())) {
                result.setOriginPlace("市外");
            } else if ("3".equals(result.getOriginPlace())) {
                result.setOriginPlace("省外");
            } else {
                result.setOriginPlace("本市");
            }
        }
        return resultList;
    }

    /**
     * 违禁药物检测及屠宰检验情况表  2025-10-10
     *
     * @param req 查询条件
     * @return 集合
     */
    @Override
    public List<GetDailyDrugCheckAndSlaughterReportResp> selectDailyDrugCheckAndSlaughterReport(GetDailyDrugCheckAndSlaughterReportReq req){
        List<GetDailyDrugCheckAndSlaughterReportResp> resultList = slaughterBatchMapper.selectDailyDrugCheckAndSlaughterReport(req);

        for (GetDailyDrugCheckAndSlaughterReportResp result:resultList){
            //宰前合格数量
            Integer beforeAmount = result.getAmount() - result.getIllnessDeadAmount() - result.getIllnessDiseaseAmount() - result.getRoadDealAmount() - result.getSnapKillAmount() - result.getDealAmount();
            result.setTuzaiAmount(beforeAmount);
            result.setQualifiedAmountBefore(beforeAmount);
            //宰后合格数量 = 宰前合格数量-生产检疫不合格的白条胴体
            result.setQualifiedAmountAfter(beforeAmount - result.getUnqualifiedDongAmount());

            //查询对应的检查结果
            DrugCheckDTO drugResult = slaughterBatchMapper.getDrug(result.getEntranceBatchId(),"违禁药物");
            if(drugResult!=null){
                drugResult.setExamineItemsStr(parseExamineItems(drugResult.getExamineItems()));
            }
            result.setDrugResult(drugResult);

            DrugCheckDTO antibioticResult = slaughterBatchMapper.getDrug(result.getEntranceBatchId(),"抗生素");
            if(antibioticResult!=null){
                antibioticResult.setExamineItemsStr(parseExamineItems(antibioticResult.getExamineItems()));
            }
            result.setAntibioticResult(antibioticResult);
        }
        return resultList;
    }

    //将检查结果转换成导出需要的可读内容
    private String parseExamineItems(String originStr){
        //把检查详情从json字符串转成可读的信息，因为数据会导出使用
        try {
            // 转换为
            String standardJson = "[" + originStr + "]";
            ObjectMapper objectMapper = new ObjectMapper();
            List<List<Map<String, Object>>> examineItems = objectMapper.readValue(standardJson,
                    new TypeReference<List<List<Map<String, Object>>>>() {});

            StringBuilder examineItemsStr = new StringBuilder();
            // 遍历结果
            for (int i = 0; i < examineItems.size(); i++) {
                if(i>0){
                    examineItemsStr.append("\n");
                }
                for (Map<String, Object> item : examineItems.get(i)) {
                    String itemStr = item.get("name") + ":" + item.get("value") + ";";
                    examineItemsStr.append(itemStr);
                }
            }
            return String.valueOf(examineItemsStr);

        } catch (Exception e) {
            log.error("转换检查结果内容失败："+e.getMessage());
        }
        return null;
    }

    /**
     * 生猪屠宰环节无害化处理表  2025-10-11
     *
     * @param req 查询条件
     * @return 集合
     */
    @Override
    public List<GetDailyHarmlessReportResp> selectDailyHarmlessReport(GetDailyHarmlessReportReq req){
        List<GetDailyHarmlessReportResp> resultList = slaughterBatchMapper.selectDailyHarmlessReport(req);
        for (GetDailyHarmlessReportResp result:resultList){
            if(result.getEntranceBatchId() != null){
                List<ProduceCheckDTO> checkResultList = slaughterBatchMapper.getProduceCheck(result.getEntranceBatchId());
                for (ProduceCheckDTO checkResult:checkResultList){
                    checkResult.setUnqualifiedNumStr(new BigDecimal(checkResult.getUnqualifiedNum().toString()).stripTrailingZeros().toPlainString()+checkResult.getUnit());
                }
                result.setProduceCheckVos(checkResultList);
            }else{
                List<ProduceCheckDTO> checkResultList = new ArrayList<ProduceCheckDTO>();
                ProduceCheckDTO checkResult = new ProduceCheckDTO();
                checkResult.setProduceName(result.getProduceName());
                checkResult.setUnit(result.getUnit());
                checkResult.setUnqualifiedNum(result.getUnqualifiedNum());
                checkResult.setUnqualifiedNumStr(new BigDecimal(result.getUnqualifiedNum().toString()).stripTrailingZeros().toPlainString()+result.getUnit());
                checkResultList.add(checkResult);
                result.setProduceCheckVos(checkResultList);
            }

        }
        return resultList;
    }

    /**
     * 生猪产品出场情况表  2025-10-12
     *
     * @param req 查询条件
     * @return 集合
     */
    @Override
    public List<GetDailyOutputReportResp> selectDailyOutputReport(GetDailyOutputReportReq req){
        List<GetDailyOutputReportResp> resultList = slaughterBatchMapper.selectDailyOutputReport(req);
        for (GetDailyOutputReportResp result:resultList){
            result.setAmountStr_1(result.getAmount_1() + result.getUnit());
            result.setWeightStr_1(result.getWeight_1() + "kg");

            result.setAmountStr_2(result.getAmount_2() + result.getUnit());
            result.setWeightStr_2(result.getWeight_2() + "kg");

            result.setAmountStr_3(result.getAmount_3() + result.getUnit());
            result.setWeightStr_3(result.getWeight_3() + "kg");
        }
        return resultList;
    }

    @Override
    public List<JsStockInfo> selectStockReport(ExportReportReq exportConfig) {


        return slaughterBatchMapper.selectStockReport(exportConfig.getStartTime(),exportConfig.getEndTime());

    }

    @Override
    public List<GetZhuanYunReportResp> getZhuanYunReport(GetDailyOutputReportReq req) {
        return  slaughterBatchMapper.getZhuanYunReport(req.getStartTime(),req.getEndTime());
    }
    @Override
    public List<GetZhuanYunReportResp> selectzhuanYunReport(ExportReportReq req) {
        return  slaughterBatchMapper.getZhuanYunReport(req.getStartTime(),req.getEndTime());
    }

    @Override
    public List<GetZhaoHuiResp> getZhaoHuiReport(GetDailyOutputReportReq req) {
        return slaughterBatchMapper.getZhaoHuiReport(req.getStartTime(),req.getEndTime(),req.getAnimalType());
    }

    @Override
    public List<GetZhaoHuiResp> selectzhaoHuiReport(ExportReportReq exportConfig) {
        return slaughterBatchMapper.getZhaoHuiReport(exportConfig.getStartTime(),exportConfig.getEndTime(),exportConfig.getAnimalType());
    }

    @Override
    public List<GetZaiQianResp> getZaiQianReport(GetDailyOutputReportReq req) {
        List<GetZaiQianResp> zaiQianReport = slaughterBatchMapper.getZaiQianReport(req.getStartTime(), req.getEndTime(),req.getAnimalType());

        return zaiQianReport;
    }

    @Override
    public List<GetZaiQianResp> selectzaiQianReport(ExportReportReq exportConfig) {
        return  slaughterBatchMapper.getZaiQianReport(exportConfig.getStartTime(),exportConfig.getEndTime(),exportConfig.getAnimalType());
    }

    @Override
    public List<GetYangPinResp> getYangPinReport(GetDailyOutputReportReq req) {
        return  slaughterBatchMapper.getYangPinReport(req.getStartTime(),req.getEndTime());
    }
    @Override
    public List<GetYangPinResp> selectyangPinReport(ExportReportReq exportConfig){
//        List<GetYangPinResp> yangPinReport = slaughterBatchMapper.getYangPinReport(exportConfig.getStartTime(), exportConfig.getEndTime());
        List<GetYangPinResp> getYangPinResps = processReports(exportConfig.getStartTime(), exportConfig.getEndTime());

        return getYangPinResps;
    }

    @Override
    public List<JingYangPinResp> getDaiZaiReport(GetDailyOutputReportReq req) {
        return  slaughterBatchMapper.getDaiZaiReport(req.getStartTime(),req.getEndTime());
    }
    @Override
    public List<JingYangPinResp> selectdaiZaiReport(ExportReportReq req) {
        return  slaughterBatchMapper.getDaiZaiReport(req.getStartTime(),req.getEndTime());
    }

    @Override
    public List<RunChagnResp> getRuChangReport(GetDailyOutputReportReq req) {
        return  slaughterBatchMapper.getRuChangReport(req.getStartTime(),req.getEndTime(),req.getAnimalType());
    }
    @Override
    public List<RunChagnResp> selectruChangReport(ExportReportReq req) {
        return  slaughterBatchMapper.getRuChangReport(req.getStartTime(),req.getEndTime(),req.getAnimalType());
    }
    @Override
    public List<ChuChagnResp> getChuChangReport(GetDailyOutputReportReq req) {
        return  slaughterBatchMapper.getChuChangReport(req.getStartTime(),req.getEndTime());
    }
    @Override
    public List<ChuChagnResp> selectchuChangReport(ExportReportReq req) {
        return  slaughterBatchMapper.getChuChangReport(req.getStartTime(),req.getEndTime());
    }
    @Override
    public List<FuJianResp> getFuJianReport(GetDailyOutputReportReq req) {
        return  slaughterBatchMapper.getFuJianReport(req.getStartTime(),req.getEndTime());
    }
    @Override
    public List<FuJianResp> selectFuJianReport(ExportReportReq req) {
        return  slaughterBatchMapper.getFuJianReport(req.getStartTime(),req.getEndTime());
    }
    @Override
    public List<ZaiHouResp> getZaiHouReport(GetDailyOutputReportReq req) {
        return  slaughterBatchMapper.getZaiHouReport(req.getStartTime(),req.getEndTime(),req.getAnimalType());
    }
    @Override
    public List<ZaiHouResp> selectzaiHouReport(ExportReportReq req) {
        return  slaughterBatchMapper.getZaiHouReport(req.getStartTime(),req.getEndTime(),req.getAnimalType());
    }
    @Override
    public List<XunChaDel> getXunChaReport(GetDailyOutputReportReq req) {
        List<XunChaDel> xunChaResps = slaughterBatchMapper.selectXunChaDelReport(req.getStartTime(), req.getEndTime());
        return xunChaResps;
    }

    @Override
    public List<GysResp> gysReport(GetDailyOutputReportReq req) {
        return slaughterBatchMapper.gysReport(req.getStartTime(), req.getEndTime());
    }
    @Override
    public List<TuZaiShengChanResp> tuzaiShengChanReport(GetDailyOutputReportReq req) {
        return slaughterBatchMapper.tuzaiShengChanReport(req.getStartTime(), req.getEndTime(),req.getAnimalType());
    }

    @Override
    public  List<TuZaiShengChanResp> selecttuzaiShengChanReport(ExportReportReq exportConfig) {
        return slaughterBatchMapper.tuzaiShengChanReport(exportConfig.getStartTime(), exportConfig.getEndTime(),exportConfig.getAnimalType());
    }

    @Override
    public List<XunChaRespDto> selectXunChaReport(ExportReportReq req, HttpServletResponse response) {
        List<XunChaResp> xunChaResps = slaughterBatchMapper.selectXunChaReport(req.getStartTime(), req.getEndTime());
        return xunChaResps.stream()
                .map(resp -> {
                    XunChaRespDto dto = new XunChaRespDto();
                    dto.setPointName(resp.getPointName());
                    try {
                        // 添加JSON解析异常捕获
                        dto.setChilDtos(JSONUtil.toList(resp.getAbnormalDesc(), XunChaRespChilDto.class));
                    } catch (Exception e) {
                        log.error("JSON解析异常: pointName={}, error={}", resp.getPointName(), e.getMessage());
                        dto.setChilDtos(Collections.emptyList()); // 避免空指针
                    }
                    return dto;
                })
                .collect(Collectors.toList());
    }


    public List<GetYangPinResp> processReports( Date startTime, Date endTime) {

        // 1. 预处理项目配置（只需查询一次）
        Map<String, GetEnvCheck> projectConfigMap = slaughterBatchMapper.getProect().stream()
                .collect(Collectors.toMap(
                        GetEnvCheck::getProjectName,
                        project -> project,
                        (v1, v2) -> v1 // 处理重复key的情况
                ));

        // 2. 批量获取报告数据
        List<GetYangPinResp> reports = slaughterBatchMapper.getYangPinReport(startTime, endTime);

        // 3. 遍历处理
        reports.forEach(report -> {
            List<Map> items = JSONUtil.toList(
                    report.getExamineItems(),
                    Map.class
            );

            items.forEach(item -> {
                String projectName = (String)item.get("name");
                String value =  (String)item.get("value");

                // 4. 使用预处理的映射表
                GetEnvCheck projectConfig = projectConfigMap.get(projectName);

                if (projectConfig != null) {
                    try {
                        BeanUtils.setProperty(report,projectConfig.getCheckContent(),value);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }

                } else {
                    log.warn("未找到项目配置: {}", projectName);
                }
            });
        });
      return  reports ;
    }


}
