package com.zksy.web.controller.basicData;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zksy.common.core.domain.AjaxResult;
import com.zksy.system.basicData.domain.*;
import com.zksy.system.basicData.domain.vo.CheckResultVo;
import com.zksy.system.basicData.domain.vo.QuarterYoYVo;
import com.zksy.system.basicData.mapper.*;
import com.zksy.system.basicData.service.CrmOverviewDataService;
import com.zksy.system.config.StrMapperMap;
import com.zksy.utils.SearchUtil;
import lombok.SneakyThrows;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/crmOverviewData")
public class CrmOverviewDataController {
    @Autowired
    private CrmOverviewDataService crmOverviewDataService;
    @Autowired
    private ObjectMapper objectMapper;
    @Autowired
    private StrMapperMap strMapperMap;
    @Autowired
    private CrmHighTechZoneEnterprisesMapper crmHighTechZoneEnterprisesMapper;

    @SneakyThrows
    @GetMapping("/checkByList")
    public AjaxResult checkByList(String listJSON, Integer pageNum, Integer pageSize, String conditionJson) {
        List list = objectMapper.readValue(listJSON, List.class);
        Page<CrmHighTechZoneEnterprises> page = crmHighTechZoneEnterprisesMapper.selectPage(new Page<CrmHighTechZoneEnterprises>(pageNum, pageSize), SearchUtil.parseWhereSql(conditionJson));
        List<CrmHighTechZoneEnterprises> enterprises = page.getRecords();
//        List<CrmHighTechZoneEnterprises> enterprises = crmHighTechZoneEnterprisesMapper.selectList(null);
        List<CheckResultVo> vos = enterprises.stream().map(q -> {
            CheckResultVo vo = new CheckResultVo();
            vo.setEnterpriseName(q.getEnterpriseName());
            vo.setUniCode(q.getUnifiedSocialCreditCode());
            return vo;
        }).collect(Collectors.toList());
        list.forEach(q -> {
            Object mapper = strMapperMap.contianer.get(q);
            if (mapper != null) {
                processCase((String) q, mapper, vos);
            }
        });
        AjaxResult result = new AjaxResult(200, "success", vos);
        result.put("total", page.getTotal());
        return result;
//        return crmOverviewDataService.checkByList(list);
    }
    private void processCase(String q, Object mapper, List<CheckResultVo> vos) {
        switch (q) {
            case "a":
                processA(mapper, vos);
                break;
            case "b1":
                processCrmOutputValue(vos, q, CrmOutputValue::getFirstQuarterAmount, CheckResultVo::setB1,LocalDate.now().getYear());
                break;
            case "b2":
                processCrmOutputValue(vos, q, CrmOutputValue::getSecondQuarterAmount, CheckResultVo::setB2,LocalDate.now().getYear());
                break;
            case "b3":
                processCrmOutputValue(vos, q, CrmOutputValue::getThirdQuarterAmount, CheckResultVo::setB3,LocalDate.now().getYear());
                break;
            case "b4":
                processCrmOutputValue(vos, q, CrmOutputValue::getFourthQuarterAmount, CheckResultVo::setB4,LocalDate.now().getYear());
                break;
            case "b6":
                processCrmOutputValue(vos, q, CrmOutputValue::getFirstQuarterAmount, CheckResultVo::setB6,LocalDate.now().getYear()-1);
                break;
            case "b7":
                processCrmOutputValue(vos, q, CrmOutputValue::getSecondQuarterAmount, CheckResultVo::setB7,LocalDate.now().getYear()-1);
                break;
            case "b8":
                processCrmOutputValue(vos, q, CrmOutputValue::getThirdQuarterAmount, CheckResultVo::setB8,LocalDate.now().getYear()-1);
                break;
            case "b9":
                processCrmOutputValue(vos, q, CrmOutputValue::getFourthQuarterAmount, CheckResultVo::setB9,LocalDate.now().getYear()-1);
                break;
            case "c1":
                processCrmEnterpriseTaxPaymentInfo(vos, q, CrmEnterpriseTaxPaymentInfo::getFirstQuarterAmount, CheckResultVo::setC1,LocalDate.now().getYear());
                break;
            case "c2":
                processCrmEnterpriseTaxPaymentInfo(vos, q, CrmEnterpriseTaxPaymentInfo::getSecondQuarterAmount, CheckResultVo::setC2,LocalDate.now().getYear());
                break;
            case "c3":
                processCrmEnterpriseTaxPaymentInfo(vos, q, CrmEnterpriseTaxPaymentInfo::getThirdQuarterAmount, CheckResultVo::setC3,LocalDate.now().getYear());
                break;
            case "c4":
                processCrmEnterpriseTaxPaymentInfo(vos, q, CrmEnterpriseTaxPaymentInfo::getFourthQuarterAmount, CheckResultVo::setC4,LocalDate.now().getYear());
                break;
            case "c6":
                processCrmEnterpriseTaxPaymentInfo(vos, q, CrmEnterpriseTaxPaymentInfo::getFirstQuarterAmount, CheckResultVo::setC6,LocalDate.now().getYear()-1);
                break;
            case "c7":
                processCrmEnterpriseTaxPaymentInfo(vos, q, CrmEnterpriseTaxPaymentInfo::getSecondQuarterAmount, CheckResultVo::setC7,LocalDate.now().getYear()-1);
                break;
            case "c8":
                processCrmEnterpriseTaxPaymentInfo(vos, q, CrmEnterpriseTaxPaymentInfo::getThirdQuarterAmount, CheckResultVo::setC8,LocalDate.now().getYear()-1);
                break;
            case "c9":
                processCrmEnterpriseTaxPaymentInfo(vos, q, CrmEnterpriseTaxPaymentInfo::getFourthQuarterAmount, CheckResultVo::setC9,LocalDate.now().getYear()-1);
                break;
            case "dd":
                processDd(mapper, vos);
                break;
            case "de":
                processDe(mapper, vos);
                break;
            case "df":
                processDf(mapper, vos);
                break;
            case "dg":
                processDg(mapper, vos);
                break;
            case "dh":
                processDh(mapper, vos);
                break;
            case "di":
                processDi(mapper, vos);
                break;
            case "dj":
                processDj(mapper, vos);
                break;
            case "dk":
                processDk(mapper, vos);
                break;
            case "dl":
                processDl(mapper, vos);
                break;
            case "dm":
                processDm(mapper, vos);
                break;
            case "dn":
                processDn(mapper, vos);
                break;
            case "dp":
                processDp(mapper, vos);
                break;
            case "dq":
                processDq(mapper, vos);
                break;
            case "dr":
                processDr(mapper, vos);
                break;
            case "dr1":
                processDr1(mapper, vos);
                break;
            case "ds":
                processDs(mapper, vos);
                break;
            case "dt":
                processDt(mapper, vos);
                break;
            case "du":
                processDu(mapper, vos);
                break;
            case "dv":
                processDv(mapper, vos);
                break;
            case "dw1":
                processWaterUsage(vos, q,CrmQuarterlyWaterUsage::getFirstQuarterUsage, CheckResultVo::setDw1,LocalDate.now().getYear());
                break;
            case "dw2":
                processWaterUsage(vos, q,CrmQuarterlyWaterUsage::getSecondQuarterUsage, CheckResultVo::setDw2,LocalDate.now().getYear());
                break;
            case "dw3":
                processWaterUsage(vos, q,CrmQuarterlyWaterUsage::getThirdQuarterUsage, CheckResultVo::setDw3,LocalDate.now().getYear());
                break;
            case "dw4":
                processWaterUsage(vos, q,CrmQuarterlyWaterUsage::getFourthQuarterUsage, CheckResultVo::setDw4,LocalDate.now().getYear());
                break;
            case "dw6":
                processWaterUsage(vos, q,CrmQuarterlyWaterUsage::getFirstQuarterUsage, CheckResultVo::setDw6,LocalDate.now().getYear()-1);
                break;
            case "dw7":
                processWaterUsage(vos, q,CrmQuarterlyWaterUsage::getSecondQuarterUsage, CheckResultVo::setDw7,LocalDate.now().getYear()-1);
                break;
            case "dw8":
                processWaterUsage(vos, q,CrmQuarterlyWaterUsage::getThirdQuarterUsage, CheckResultVo::setDw8,LocalDate.now().getYear()-1);
                break;
            case "dw9":
                processWaterUsage(vos, q,CrmQuarterlyWaterUsage::getFourthQuarterUsage, CheckResultVo::setDw9,LocalDate.now().getYear()-1);
                break;
            case "dx1":
                processElectricityBill(vos, q,CrmQuarterlyElectricityBill::getFirstQuarterConsumption, CheckResultVo::setDx1,LocalDate.now().getYear());
                break;
            case "dx2":
                processElectricityBill(vos, q,CrmQuarterlyElectricityBill::getSecondQuarterConsumption, CheckResultVo::setDx2,LocalDate.now().getYear());
                break;
            case "dx3":
                processElectricityBill(vos, q,CrmQuarterlyElectricityBill::getThirdQuarterConsumption, CheckResultVo::setDx3,LocalDate.now().getYear());
                break;
            case "dx4":
                processElectricityBill(vos, q,CrmQuarterlyElectricityBill::getFourthQuarterConsumption, CheckResultVo::setDx4,LocalDate.now().getYear());
                break;
            case "dx6":
                processElectricityBill(vos, q,CrmQuarterlyElectricityBill::getFirstQuarterConsumption, CheckResultVo::setDx6,LocalDate.now().getYear()-1);
                break;
            case "dx7":
                processElectricityBill(vos, q,CrmQuarterlyElectricityBill::getSecondQuarterConsumption, CheckResultVo::setDx7,LocalDate.now().getYear()-1);
                break;
            case "dx8":
                processElectricityBill(vos, q,CrmQuarterlyElectricityBill::getThirdQuarterConsumption, CheckResultVo::setDx8,LocalDate.now().getYear()-1);
                break;
            case "dx9":
                processElectricityBill(vos, q,CrmQuarterlyElectricityBill::getFourthQuarterConsumption, CheckResultVo::setDx9,LocalDate.now().getYear()-1);
                break;
            case "dy1":
                processDy(vos, q,CrmServiceEnterpriseRevenue::getQ1Revenue, CheckResultVo::setDy1,LocalDate.now().getYear());
                break;
            case "dy2":
                processDy(vos, q,CrmServiceEnterpriseRevenue::getQ2Revenue, CheckResultVo::setDy2,LocalDate.now().getYear());
                break;
            case "dy3":
                processDy(vos, q,CrmServiceEnterpriseRevenue::getQ3Revenue, CheckResultVo::setDy3,LocalDate.now().getYear());
                break;
            case "dy4":
                processDy(vos, q,CrmServiceEnterpriseRevenue::getQ4Revenue, CheckResultVo::setDy4,LocalDate.now().getYear());
                break;
            case "dy6":
                processDy(vos, q,CrmServiceEnterpriseRevenue::getQ1Revenue, CheckResultVo::setDy6,LocalDate.now().getYear()-1);
                break;
            case "dy7":
                processDy(vos, q,CrmServiceEnterpriseRevenue::getQ2Revenue, CheckResultVo::setDy7,LocalDate.now().getYear()-1);
                break;
            case "dy8":
                processDy(vos, q,CrmServiceEnterpriseRevenue::getQ3Revenue, CheckResultVo::setDy8,LocalDate.now().getYear()-1);
                break;
            case "dy9":
                processDy(vos, q,CrmServiceEnterpriseRevenue::getQ4Revenue, CheckResultVo::setDy9,LocalDate.now().getYear()-1);
                break;
            default:
                break;
        }
    }

    private void processA(Object mapper, List<CheckResultVo> vos) {
        CrmHighTechZoneEnterprisesMapper o = (CrmHighTechZoneEnterprisesMapper) mapper;
        List<String> deductionPoints = o.getDeductionPoints();
        vos.forEach(w1 -> {
            deductionPoints.forEach(e -> {
                if (Objects.equals(w1.getUniCode(), e)) {
                    w1.setA(w1.getA() + 1);
                }
            });
        });
    }

    private void processCrmOutputValue(
            List<CheckResultVo> vos,
            String q,
            Function<CrmOutputValue, String> amountFunction,
            BiConsumer<CheckResultVo, String> setterFunction,
            Integer year
    ) {
        CrmOutputValueMapper o = (CrmOutputValueMapper) strMapperMap.contianer.get(q);
        LambdaQueryWrapper<CrmOutputValue> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CrmOutputValue::getAnnualAmount, year);
        List<CrmOutputValue> crmOutputValues = o.selectList(wrapper);
        Map<String, CrmOutputValue> crmOutputValueMap = crmOutputValues.stream()
                .collect(Collectors.toMap(CrmOutputValue::getUnifiedSocialCreditCode, v -> v));
        vos.forEach(w1 -> {
            CrmOutputValue crmOutputValue = crmOutputValueMap.get(w1.getUniCode());
            if (crmOutputValue != null) {
                setterFunction.accept(w1, amountFunction.apply(crmOutputValue));
            }
        });
    }

    private void processCrmEnterpriseTaxPaymentInfo(
            List<CheckResultVo> vos,
            String q,
            Function<CrmEnterpriseTaxPaymentInfo, String> amountFunction,
            BiConsumer<CheckResultVo, String> setterFunction,
            Integer year
    ) {
        CrmEnterpriseTaxPaymentInfoMapper o = (CrmEnterpriseTaxPaymentInfoMapper) strMapperMap.contianer.get(q);
        LambdaQueryWrapper<CrmEnterpriseTaxPaymentInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CrmEnterpriseTaxPaymentInfo::getAnnualAmount, year);
        List<CrmEnterpriseTaxPaymentInfo> list = o.selectList(wrapper);
        Map<String, CrmEnterpriseTaxPaymentInfo> map = list.stream()
                .collect(Collectors.toMap(CrmEnterpriseTaxPaymentInfo::getUnifiedSocialCreditCode, v -> v));
        vos.forEach(w1 -> {
            CrmEnterpriseTaxPaymentInfo value = map.get(w1.getUniCode());
            if (value != null) {
                setterFunction.accept(w1, amountFunction.apply(value));
            }
        });
    }
    private void processDd(Object mapper, List<CheckResultVo> vos) {
        processCommon(mapper, vos, CrmChangeRecordInformationMapper.class,
                CrmChangeRecordInformation::getUnifiedSocialCreditCode,
                CheckResultVo::setDd);
    }

    private void processDe(Object mapper, List<CheckResultVo> vos) {
        processCommon(mapper, vos, CrmAdministrativeLicenseMapper.class,
                CrmAdministrativeLicense::getUnifiedSocialCreditCode,
                CheckResultVo::setDe);
    }

    private void processDf(Object mapper, List<CheckResultVo> vos) {
        processCommon(mapper, vos, CrmAdministrativeConfirmationMapper.class,
                CrmAdministrativeConfirmation::getUnifiedSocialCreditCode,
                CheckResultVo::setDf);
    }

    private void processDg(Object mapper, List<CheckResultVo> vos) {
        processCommon(mapper, vos, CrmListedCompanyMapper.class,
                CrmListedCompany::getUnifiedSocialCreditCode,
                CheckResultVo::setDg);
    }

    private void processDh(Object mapper, List<CheckResultVo> vos) {
        processCommon(mapper, vos, CrmNewEnterpriseRecognitionDetailsMapper.class,
                CrmNewEnterpriseRecognitionDetails::getUnifiedSocialCreditCode,
                CheckResultVo::setDh);
    }

    private void processDi(Object mapper, List<CheckResultVo> vos) {
        processCommon(mapper, vos, CrmEnterpriseTechnologyRndSummaryMapper.class,
                CrmEnterpriseTechnologyRndSummary::getUnifiedSocialCreditCode,
                CheckResultVo::setDi);
    }
    private void processDj(Object mapper, List<CheckResultVo> vos) {
        processCommon(mapper, vos, CrmTechnologyEnterprisesMapper.class,
                CrmTechnologyEnterprises::getUnifiedSocialCreditCode,
                CheckResultVo::setDj);
    }

    private void processDk(Object mapper, List<CheckResultVo> vos) {
        processCommon(mapper, vos, CrmCertifiedTechnologyEnterpriseMapper.class,
                CrmCertifiedTechnologyEnterprise::getUnifiedSocialCreditCode,
                CheckResultVo::setDk);
    }

    private void processDl(Object mapper, List<CheckResultVo> vos) {
        processCommon(mapper, vos, CrmSoftwareCopyrightInformationMapper.class,
                CrmSoftwareCopyrightInformation::getUnifiedSocialCreditCode,
                CheckResultVo::setDl);
    }

    private void processDm(Object mapper, List<CheckResultVo> vos) {
        processCommon(mapper, vos, CrmPatentInformationMapper.class,
                CrmPatentInformation::getUnifiedSocialCreditCode,
                CheckResultVo::setDm);
    }

    private void processDn(Object mapper, List<CheckResultVo> vos) {
        processCommon(mapper, vos, CrmCreditRedlistInfoMapper.class,
                CrmCreditRedlistInfo::getUnifiedSocialCreditCode,
                CheckResultVo::setDn);
    }

    private void processDp(Object mapper, List<CheckResultVo> vos) {
        CrmEnterpriseTaxClassificationInfoMapper crmEnterpriseTaxClassificationInfoMapper = (CrmEnterpriseTaxClassificationInfoMapper) mapper;
        List<CrmEnterpriseTaxClassificationInfo> list = crmEnterpriseTaxClassificationInfoMapper.selectList(null);
        Map<String, String> map = list.stream()
                .collect(Collectors.toMap(CrmEnterpriseTaxClassificationInfo::getUnifiedSocialCreditCode,
                        CrmEnterpriseTaxClassificationInfo::getTaxCreditRating));
        vos.forEach(w1 -> Optional.ofNullable(map.get(w1.getUniCode()))
                .ifPresent(w1::setDp));
    }

    private void processDq(Object mapper, List<CheckResultVo> vos) {
        CrmAbnormalTaxInformationMapper crmAbnormalTaxInformationMapper = (CrmAbnormalTaxInformationMapper) mapper;
        List<CrmAbnormalTaxInformation> list = crmAbnormalTaxInformationMapper.selectList(null);
        Map<String, String> map = list.stream()
                .collect(Collectors.toMap(CrmAbnormalTaxInformation::getUnifiedSocialCreditCode,
                        CrmAbnormalTaxInformation::getIsAbnormalTaxpayer));
        vos.forEach(w1 -> Optional.ofNullable(map.get(w1.getUniCode()))
                .ifPresent(w1::setDq));
    }

    private void processDr(Object mapper, List<CheckResultVo> vos) {
        CrmEnterpriseSocialSecurityInfoMapper crmEnterpriseSocialSecurityInfoMapper = (CrmEnterpriseSocialSecurityInfoMapper) mapper;
        List<CrmEnterpriseSocialSecurityInfo> list = crmEnterpriseSocialSecurityInfoMapper.selectList(null);
        Map<String, String> map = list.stream()
                .filter(q->q.getRemarks().contains(String.valueOf(LocalDate.now().getYear())))
                .collect(Collectors.toMap(CrmEnterpriseSocialSecurityInfo::getUnifiedSocialCreditCode,
                        CrmEnterpriseSocialSecurityInfo::getAvgInsuredPersonsBand));
        vos.forEach(w1 -> Optional.ofNullable(map.get(w1.getUniCode()))
                .map(String::trim)
                .filter(q->!q.isEmpty())
                .map(Long::parseLong)
                .ifPresent(w1::setDr));
    }

    private void processDr1(Object mapper, List<CheckResultVo> vos) {
        CrmEnterpriseSocialSecurityInfoMapper crmEnterpriseSocialSecurityInfoMapper = (CrmEnterpriseSocialSecurityInfoMapper) mapper;
        List<CrmEnterpriseSocialSecurityInfo> list = crmEnterpriseSocialSecurityInfoMapper.selectList(null);
        Map<String, String> map = list.stream()
                .filter(q->q.getRemarks().contains(String.valueOf(LocalDate.now().getYear())))
                .collect(Collectors.toMap(CrmEnterpriseSocialSecurityInfo::getUnifiedSocialCreditCode,
                        CrmEnterpriseSocialSecurityInfo::getAvgMonthlyPaymentBand));
        vos.forEach(w1 -> Optional.ofNullable(map.get(w1.getUniCode()))
                .map(String::trim)
                .filter(q->!q.isEmpty())
                .map(Double::valueOf)
                .ifPresent(w1::setDr1));
    }

    private void processDs(Object mapper, List<CheckResultVo> vos) {
        CrmEnvironmentalCreditEvaluationNotificationMapper crmEnvironmentalCreditEvaluationNotificationMapper = (CrmEnvironmentalCreditEvaluationNotificationMapper) mapper;
        List<CrmEnvironmentalCreditEvaluationNotification> list = crmEnvironmentalCreditEvaluationNotificationMapper.selectList(null);
        Map<String, String> map = list.stream()
                .collect(Collectors.toMap(CrmEnvironmentalCreditEvaluationNotification::getUnifiedSocialCreditCode,
                        CrmEnvironmentalCreditEvaluationNotification::getCreditRating));
        vos.forEach(w1 -> Optional.ofNullable(map.get(w1.getUniCode()))
                .ifPresent(w1::setDs));
    }

    private void processDt(Object mapper, List<CheckResultVo> vos) {
        CrmNationalPublicCreditEvaluationInformationMapper crmNationalPublicCreditEvaluationInformationMapper = (CrmNationalPublicCreditEvaluationInformationMapper) mapper;
        List<CrmNationalPublicCreditEvaluationInformation> list = crmNationalPublicCreditEvaluationInformationMapper.selectList(null);
        Map<String, String> map = list.stream()
                .collect(Collectors.toMap(CrmNationalPublicCreditEvaluationInformation::getUnifiedSocialCreditCode,
                        CrmNationalPublicCreditEvaluationInformation::getEvaluationGrade));
        vos.forEach(w1 -> Optional.ofNullable(map.get(w1.getUniCode()))
                .ifPresent(w1::setDt));
    }

    private void processDu(Object mapper, List<CheckResultVo> vos) {
        CrmRatingAgencyInfoMapper crmRatingAgencyInfoMapper = (CrmRatingAgencyInfoMapper) mapper;
        List<CrmRatingAgencyInfo> list = crmRatingAgencyInfoMapper.selectList(null);
        Map<String, Long> map = list.stream()
                .filter(q->q.getRatingDate().contains(String.valueOf(LocalDate.now().getYear())))
                .filter(q->"AAA".equals(q.getCreditRating()))
                .collect(
                        Collectors.groupingBy(
                                CrmRatingAgencyInfo::getUnifiedSocialCreditCode,
                                Collectors.counting()
                        )
                );
        vos.forEach(w1 -> Optional.ofNullable(map.get(w1.getUniCode()))
                .ifPresent(w1::setDu));
    }

    private void processDv(Object mapper, List<CheckResultVo> vos) {
        CrmEnterpriseCreditRatingMapper crmEnterpriseCreditRatingMapper = (CrmEnterpriseCreditRatingMapper) mapper;
        List<CrmEnterpriseCreditRating> list = crmEnterpriseCreditRatingMapper.selectList(null);
        Map<String, Long> map = list.stream()
                .collect(Collectors.toMap(CrmEnterpriseCreditRating::getUnifiedSocialCreditCode,
                        CrmEnterpriseCreditRating::getRatingScore));
        vos.forEach(w1 -> Optional.ofNullable(map.get(w1.getUniCode()))
                .ifPresent(w1::setDv));
    }

    private void processWaterUsage(
            List<CheckResultVo> vos,
            String q,
            Function<CrmQuarterlyWaterUsage, String> amountFunction,
            BiConsumer<CheckResultVo, String> setterFunction,
            Integer year
    ) {
        CrmQuarterlyWaterUsageMapper o = (CrmQuarterlyWaterUsageMapper) strMapperMap.contianer.get(q);
        LambdaQueryWrapper<CrmQuarterlyWaterUsage> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CrmQuarterlyWaterUsage::getAnnual, year);
        List<CrmQuarterlyWaterUsage> value = o.selectList(wrapper);
        Map<String, CrmQuarterlyWaterUsage> map = value.stream()
                .collect(Collectors.toMap(CrmQuarterlyWaterUsage::getUnifiedSocialCreditCode, v -> v));
        vos.forEach(w1 -> {
            CrmQuarterlyWaterUsage v = map.get(w1.getUniCode());
            if (v != null) {
                setterFunction.accept(w1, amountFunction.apply(v));
            }
        });
    }

    private void processElectricityBill(
            List<CheckResultVo> vos,
            String q,
            Function<CrmQuarterlyElectricityBill, String> amountFunction,
            BiConsumer<CheckResultVo, String> setterFunction,
            Integer year
    ) {
        CrmQuarterlyElectricityBillMapper o = (CrmQuarterlyElectricityBillMapper) strMapperMap.contianer.get(q);
        LambdaQueryWrapper<CrmQuarterlyElectricityBill> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CrmQuarterlyElectricityBill::getYear, year);
        List<CrmQuarterlyElectricityBill> value = o.selectList(wrapper);
        Map<String, CrmQuarterlyElectricityBill> map = value.stream()
                .collect(Collectors.toMap(CrmQuarterlyElectricityBill::getUnifiedSocialCreditCode, v -> v));
        vos.forEach(w1 -> {
            CrmQuarterlyElectricityBill v = map.get(w1.getUniCode());
            if (v != null) {
                setterFunction.accept(w1, amountFunction.apply(v));
            }
        });
    }

    private void processDy(
            List<CheckResultVo> vos,
            String q,
            Function<CrmServiceEnterpriseRevenue, String> function,
            BiConsumer<CheckResultVo, String> consumer,
            Integer year
    ) {
        CrmServiceEnterpriseRevenueMapper o = (CrmServiceEnterpriseRevenueMapper) strMapperMap.contianer.get(q);
        LambdaQueryWrapper<CrmServiceEnterpriseRevenue> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CrmServiceEnterpriseRevenue::getRevenueYear, year.toString());
        List<CrmServiceEnterpriseRevenue> value = o.selectList(wrapper);
        Map<String, CrmServiceEnterpriseRevenue> map = value.stream()
                .collect(Collectors.toMap(CrmServiceEnterpriseRevenue::getUnifiedSocialCreditCode, v -> v));
        vos.forEach(w1 -> {
            CrmServiceEnterpriseRevenue v = map.get(w1.getUniCode());
            if (v != null) {
                consumer.accept(w1, function.apply(v));
            }
        });
    }


    private <T extends BaseMapper<R>, R> void processCommon(Object mapper, List<CheckResultVo> vos, Class<T> mapperClass,
                                                               Function<R, String> keyExtractor,
                                                               BiConsumer<CheckResultVo, Long> setter) {
        T typedMapper = mapperClass.cast(mapper);
        List<R> list = typedMapper.selectList(null);
        Map<String, Long> map = list.stream()
                .collect(Collectors.groupingBy(keyExtractor, Collectors.counting()));

        vos.forEach(w1 -> {
            Optional.ofNullable(map.get(w1.getUniCode()))
                    .ifPresent(count -> setter.accept(w1, count));
        });
    }
}
