package com.ningdatech.carapi.report.manage;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.ningdatech.basic.function.VUtils;
import com.ningdatech.basic.model.PageVo;
import com.ningdatech.basic.util.StrPool;
import com.ningdatech.carapi.car.vehicle.contants.VehicleContant;
import com.ningdatech.carapi.common.constant.UserRoleTypeEnum;
import com.ningdatech.carapi.common.contants.DefValConstants;
import com.ningdatech.carapi.report.constant.DataUploadAuditStatusEnum;
import com.ningdatech.carapi.report.constant.DataUploadAuditTypeEnum;
import com.ningdatech.carapi.report.constant.UploadDataTypeEnum;
import com.ningdatech.carapi.report.model.dto.ReqBulkCementLogFacStaDataUploadDTO;
import com.ningdatech.carapi.report.model.entity.BulkCementDirectReportSystemAuditInfo;
import com.ningdatech.carapi.report.model.entity.BulkCementDirectReportSystemAuditRecord;
import com.ningdatech.carapi.report.model.entity.BulkCementDirectReportSystemDataRelevance;
import com.ningdatech.carapi.report.model.entity.BulkCementLogisticFacilityStatisticAnnualReport;
import com.ningdatech.carapi.report.model.po.ReqBulkCementLogFacStaDataUploadPO;
import com.ningdatech.carapi.report.model.po.ReqDataUploadListPO;
import com.ningdatech.carapi.report.model.vo.ResBulkCementLogFacStaDataUploadDetailVO;
import com.ningdatech.carapi.report.model.vo.ResBulkCementLogFacStaRelatedDataVO;
import com.ningdatech.carapi.report.model.vo.ResDataUploadListVO;
import com.ningdatech.carapi.report.service.IBulkCementDirectReportSystemAuditInfoService;
import com.ningdatech.carapi.report.service.IBulkCementDirectReportSystemAuditRecordService;
import com.ningdatech.carapi.report.service.IBulkCementDirectReportSystemDataRelevanceService;
import com.ningdatech.carapi.report.service.IBulkCementLogisticFacilityStatisticAnnualReportService;
import com.ningdatech.carapi.sys.entity.dto.CompanyDTO;
import com.ningdatech.carapi.sys.entity.dto.RegionDTO;
import com.ningdatech.carapi.sys.helper.CompaniesCacheHelper;
import com.ningdatech.carapi.sys.helper.RegionsCacheHelper;
import com.ningdatech.carapi.user.security.auth.model.UserInfoDetails;
import com.ningdatech.carapi.user.util.LoginUserUtil;

import cn.hutool.core.collection.CollUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * @author CMM
 * @since 2023/09/28 11:15
 */
@Component
@RequiredArgsConstructor
@Slf4j
public class BulkCementLogFacStaManage {

    private final IBulkCementDirectReportSystemAuditRecordService auditRecordService;
    private final IBulkCementDirectReportSystemAuditInfoService auditInfoService;
    private final RegionsCacheHelper regionsCacheHelper;
    private final IBulkCementDirectReportSystemDataRelevanceService dataRelevanceService;
    private final IBulkCementLogisticFacilityStatisticAnnualReportService bulkCementLogFacStaService;
    private final CompaniesCacheHelper companiesCacheHelper;

    public PageVo<ResDataUploadListVO> dataUploadList(ReqDataUploadListPO req) {

        UserInfoDetails userDetail = LoginUserUtil.loginUserDetail();
        Long regionId = userDetail.getRegionId();
        Page<BulkCementDirectReportSystemDataRelevance> page = req.page();
        // 根据所属区域查出对应的散装水泥物流设施统计年报数据上报记录
        // (每个上报年份对应多个设备名称的数据，需要从数据关联表中查询)
        LambdaQueryWrapper<BulkCementDirectReportSystemDataRelevance> wrapper = Wrappers.lambdaQuery(BulkCementDirectReportSystemDataRelevance.class);
        // 获取入参
        Integer reportStartYear = req.getReportStartYear();
        Integer reportEndYear = req.getReportEndYear();
        Integer auditStatus = req.getAuditStatus();
        wrapper.ge(Objects.nonNull(reportStartYear), BulkCementDirectReportSystemDataRelevance::getReportYear, reportStartYear)
                .le(Objects.nonNull(reportEndYear), BulkCementDirectReportSystemDataRelevance::getReportYear, reportEndYear)
                .eq(Objects.nonNull(auditStatus),BulkCementDirectReportSystemDataRelevance::getAuditStatus,auditStatus)
                // 市级/省级散办单位可根据区域分别查出对应的关联数据
                // 其中市级关联数据对应的数据ID列表为对应上报数据关联数据的ID
                // 省级关联数据对应的数据ID列表为各市级关联数据的ID(温台舟使用量关联数据对应的数据ID列表
                // 仍为对应上报数据的ID)
                .eq(BulkCementDirectReportSystemDataRelevance::getAuditDataType,UploadDataTypeEnum.BULK_CEMENT_LOGISTIC_FACILITY_STATISTIC_ANNUAL_REPORT.getCode())
                .eq(BulkCementDirectReportSystemDataRelevance::getRegionId,regionId)
                .orderByDesc(BulkCementDirectReportSystemDataRelevance::getReportYear);
                //.isNotNull(BulkCementDirectReportSystemDataRelevance::getAuditInfoId);
        dataRelevanceService.page(page,wrapper);

        List<BulkCementDirectReportSystemDataRelevance> records = page.getRecords();
        if (CollUtil.isEmpty(records)){
            return PageVo.empty();
        }
        // 获取审核信息
        List<Long> auditInfoIdList = records.stream().map(BulkCementDirectReportSystemDataRelevance::getAuditInfoId).collect(Collectors.toList());
        Map<Long, BulkCementDirectReportSystemAuditInfo> auditInfoMap = auditInfoService.list(Wrappers.lambdaQuery(BulkCementDirectReportSystemAuditInfo.class).in(BulkCementDirectReportSystemAuditInfo::getId, auditInfoIdList))
                .stream().collect(Collectors.toMap(BulkCementDirectReportSystemAuditInfo::getId, v -> v));
        List<ResDataUploadListVO> resVos = records.stream().map(r -> {
            ResDataUploadListVO vo = new ResDataUploadListVO();
            Integer reportYear = r.getReportYear();
            vo.setRegionId(r.getRegionId());
            vo.setReportYear(reportYear);
            vo.setAuditDataId(r.getId());

            BulkCementDirectReportSystemAuditInfo auditInfo = auditInfoMap.get(r.getAuditInfoId());
            if (Objects.nonNull(auditInfo)) {
                vo.setAuditOpinion(auditInfo.getAuditOpinion());
            }
            vo.setAuditStatus(r.getAuditStatus());
            String desc = DataUploadAuditStatusEnum.getDescByCode(r.getAuditStatus());
            vo.setAuditStatusName(desc);
            vo.setCreateOn(r.getCreateOn());
            return vo;
        }).collect(Collectors.toList());
        return PageVo.of(resVos, page.getTotal());
    }

    @Transactional(rollbackFor = Exception.class)
    public String bulkCementLogFacStaDataUpload(ReqBulkCementLogFacStaDataUploadPO req) {
        // 获取登录用户信息
        UserInfoDetails userDetail = LoginUserUtil.loginUserDetail();
        Integer reportYear = req.getReportYear();
        VUtils.isTrue(Objects.isNull(reportYear)).throwMessage("请选择上报年份!");
        Long regionId = userDetail.getRegionId();

        
        // 如果登录用户为区县散办
        if (UserRoleTypeEnum.REGION_ADMIN_ROLE_ID.getId().equals(userDetail.getRoleId())) {

            // 先提交市级审核申请
            BulkCementDirectReportSystemAuditInfo cityAuditInfo = new BulkCementDirectReportSystemAuditInfo();
            assemblyAuditInfo(cityAuditInfo, DataUploadAuditStatusEnum.UNDER_AUDIT, userDetail);
            cityAuditInfo.setAuditType(DataUploadAuditTypeEnum.CITY_AUDIT.getCode());
            auditInfoService.save(cityAuditInfo);

            // 发放库数据
            ReqBulkCementLogFacStaDataUploadDTO issueLibraryData = req.getIssueLibraryData();
            VUtils.isTrue(Objects.isNull(issueLibraryData)).throwMessage("请传入发放库数据!");
            // 中转库数据
            ReqBulkCementLogFacStaDataUploadDTO transferLibraryData = req.getTransferLibraryData();
            VUtils.isTrue(Objects.isNull(transferLibraryData)).throwMessage("请传入中转库数据!");
            // 固定接收库数据
            ReqBulkCementLogFacStaDataUploadDTO fixedReceiveLibraryData = req.getFixedReceiveLibraryData();
            VUtils.isTrue(Objects.isNull(fixedReceiveLibraryData)).throwMessage("请传入固定接收库数据!");
            // 合并保存（虽然每个设备名称的数据单独按一条数据保存，但审核数据仍在一条中）
            List<ReqBulkCementLogFacStaDataUploadDTO> dataList = Lists.newArrayList();
            dataList.add(issueLibraryData);
            dataList.add(transferLibraryData);
            dataList.add(fixedReceiveLibraryData);

            // 创建区县关联数据信息(对应每个设备名称的数据关系为一对多)
            BulkCementDirectReportSystemDataRelevance countryData = dataRelevanceService.getOne(Wrappers.lambdaQuery(BulkCementDirectReportSystemDataRelevance.class)
                    .eq(BulkCementDirectReportSystemDataRelevance::getRegionId, regionId)
                    .eq(BulkCementDirectReportSystemDataRelevance::getReportYear, reportYear)
                    .eq(BulkCementDirectReportSystemDataRelevance::getAuditDataType, UploadDataTypeEnum.BULK_CEMENT_LOGISTIC_FACILITY_STATISTIC_ANNUAL_REPORT.getCode()));

            BulkCementDirectReportSystemDataRelevance countryRelevanceData = new BulkCementDirectReportSystemDataRelevance();
            // 区县的区域ID
            // 获取所在市的区域ID
            RegionDTO regionDto = regionsCacheHelper.getByRegionId(regionId);
            Long parentId = regionDto.getParentId();
            // 判断上报年份所在市的市级关联数据不存在
            RegionDTO cityRegionDto = regionsCacheHelper.getByRegionId(parentId);
            BulkCementDirectReportSystemDataRelevance cityData = dataRelevanceService.getOne(Wrappers.lambdaQuery(BulkCementDirectReportSystemDataRelevance.class)
                    .eq(BulkCementDirectReportSystemDataRelevance::getRegionId, parentId)
                    .eq(BulkCementDirectReportSystemDataRelevance::getAuditType,DataUploadAuditTypeEnum.CITY_AUDIT.getCode())
                    .eq(BulkCementDirectReportSystemDataRelevance::getReportYear, reportYear)
                    .eq(BulkCementDirectReportSystemDataRelevance::getAuditDataType, UploadDataTypeEnum.BULK_CEMENT_LOGISTIC_FACILITY_STATISTIC_ANNUAL_REPORT.getCode()));
            // 判断当前地区当前上报年份数据是否已经存在,如果已经存在，更新原数据
            checkUploadData(reportYear, regionId, cityData);
            // 说明为重新提交
            if (Objects.nonNull(countryData)){
                // 先删除关联的已经保存的各设备名称的数据
                String auditDataIdList = countryData.getAuditDataIdList();
                if (StringUtils.isNotBlank(auditDataIdList)){
                    List<Long> idList = Arrays.stream(auditDataIdList.split(StrPool.COMMA)).map(Long::valueOf).collect(Collectors.toList());
                    if (CollUtil.isNotEmpty(idList)){
                        bulkCementLogFacStaService.remove(Wrappers.lambdaQuery(BulkCementLogisticFacilityStatisticAnnualReport.class)
                                .in(BulkCementLogisticFacilityStatisticAnnualReport::getId,idList));
                    }
                }
                // 更新市级关联数据
                updateCityData(cityData,countryData);
                // 删除被退回的数据
                dataRelevanceService.removeById(countryData);
            }
            assemblyRelevanceData(userDetail, reportYear, countryRelevanceData);
            countryRelevanceData.setAuditDataType(UploadDataTypeEnum.BULK_CEMENT_LOGISTIC_FACILITY_STATISTIC_ANNUAL_REPORT.getCode());
            countryRelevanceData.setAuditStatus(DataUploadAuditStatusEnum.UNDER_AUDIT.getCode());
            countryRelevanceData.setAuditInfoId(cityAuditInfo.getId());
            countryRelevanceData.setUnitResponsiblePerson(req.getUnitResponsiblePerson());
            countryRelevanceData.setPreparer(req.getPreparer());
            countryRelevanceData.setReviewer(req.getReviewer());
            countryRelevanceData.setSubmissionDate(req.getSubmissionDate());
            countryRelevanceData.setRegionId(userDetail.getRegionId());
            countryRelevanceData.setCompanyId(userDetail.getCompanyId());
            List<Long> auditDataIdList = Lists.newArrayList();
            // 保存本次上报数据信息
            for (ReqBulkCementLogFacStaDataUploadDTO uploadDto : dataList) {
                BulkCementLogisticFacilityStatisticAnnualReport bulkCementLogFacStaAnnualReport =
                        new BulkCementLogisticFacilityStatisticAnnualReport();
                assemblyData(uploadDto, userDetail, bulkCementLogFacStaAnnualReport);
                bulkCementLogFacStaAnnualReport.setAuditInfoId(cityAuditInfo.getId());
                bulkCementLogFacStaAnnualReport.setAuditStatus(DataUploadAuditStatusEnum.UNDER_AUDIT.getCode());
                bulkCementLogFacStaService.save(bulkCementLogFacStaAnnualReport);
                auditDataIdList.add(bulkCementLogFacStaAnnualReport.getId());
            }
            // 保存关联数据ID集合(一条关联数据对应多条不同设备名称的数据)
            String idListStr = auditDataIdList.stream().map(String::valueOf).collect(Collectors.joining(StrPool.COMMA));
            countryRelevanceData.setAuditDataIdList(idListStr);
            dataRelevanceService.saveOrUpdate(countryRelevanceData);

            // 补充数据审核表信息
            BulkCementDirectReportSystemAuditRecord auditRecord = new BulkCementDirectReportSystemAuditRecord();
            assemblyAuditRecord(userDetail, countryRelevanceData.getId(), cityAuditInfo.getId(), auditRecord);
            auditRecord.setReportYear(reportYear);
            auditRecord.setAuditType(DataUploadAuditTypeEnum.CITY_AUDIT.getCode());
            auditRecordService.save(auditRecord);

            // 补充所在市的关联数据信息
            if (Objects.isNull(cityData)) {
                BulkCementDirectReportSystemDataRelevance cityRelevanceData = new BulkCementDirectReportSystemDataRelevance();
                assemblyRelevanceData(userDetail, reportYear, cityRelevanceData);
                cityRelevanceData.setRegionId(parentId);
                // 获取所在市散装中心所属的管理企业ID
                CompanyDTO companyDto = companiesCacheHelper.getByName(cityRegionDto.getRegionName() + VehicleContant.ADMIN_COMPANY_NAME);
                if (Objects.nonNull(companyDto)) {
                    cityRelevanceData.setCompanyId(companyDto.getId());
                }
                cityRelevanceData.setAuditType(DataUploadAuditTypeEnum.CITY_AUDIT.getCode());
                // 有新上报的数据，就更新关联数据状态为未上报
                cityRelevanceData.setAuditDataType(UploadDataTypeEnum.BULK_CEMENT_LOGISTIC_FACILITY_STATISTIC_ANNUAL_REPORT.getCode());
                cityRelevanceData.setAuditStatus(DataUploadAuditStatusEnum.NOT_REPORT.getCode());
                dataRelevanceService.saveOrUpdate(cityRelevanceData);
            }

        }
        // 如果登录用户是市级散办,更新审核状态(未上报、被退回)为审核中，并提交省级审核信息和审核记录
        else if (UserRoleTypeEnum.BULK_CEMENT_ADMIN_ROLE_ID.getId().equals(userDetail.getRoleId())) {

            // 补充省散办关联数据信息
            Long cityRelevanceDataId = req.getId();
            VUtils.isTrue(Objects.isNull(cityRelevanceDataId)).throwMessage("请传入关联数据ID!");

            // 提交省级审核申请
            BulkCementDirectReportSystemAuditInfo provinceAuditInfo = new BulkCementDirectReportSystemAuditInfo();
            assemblyAuditInfo(provinceAuditInfo, DataUploadAuditStatusEnum.UNDER_AUDIT, userDetail);
            provinceAuditInfo.setAuditType(DataUploadAuditTypeEnum.PROVINCE_AUDIT.getCode());
            auditInfoService.save(provinceAuditInfo);

            // 更新市级关联数据审核状态为审核中
            BulkCementDirectReportSystemDataRelevance cityRelevanceData = dataRelevanceService.getById(cityRelevanceDataId);
            VUtils.isTrue(Objects.isNull(cityRelevanceData)).throwMessage("数据不存在!");
            // 关联审核信息ID
            cityRelevanceData.setUnitResponsiblePerson(req.getUnitResponsiblePerson());
            cityRelevanceData.setPreparer(req.getPreparer());
            cityRelevanceData.setReviewer(req.getReviewer());
            cityRelevanceData.setSubmissionDate(req.getSubmissionDate());
            cityRelevanceData.setAuditInfoId(provinceAuditInfo.getId());
            cityRelevanceData.setAuditStatus(DataUploadAuditStatusEnum.UNDER_AUDIT.getCode());
            cityRelevanceData.setUpdateOn(LocalDateTime.now());
            cityRelevanceData.setUpdateBy(userDetail.getUserId());
            cityRelevanceData.setUnitResponsiblePerson(req.getUnitResponsiblePerson());
            cityRelevanceData.setPreparer(req.getPreparer());
            cityRelevanceData.setReviewer(req.getReviewer());
            cityRelevanceData.setSubmissionDate(req.getSubmissionDate());
            dataRelevanceService.updateById(cityRelevanceData);

            // 判断上报月份省关联数据是否存在
            BulkCementDirectReportSystemDataRelevance provinceData = dataRelevanceService.getOne(Wrappers.lambdaQuery(BulkCementDirectReportSystemDataRelevance.class)
                    .eq(BulkCementDirectReportSystemDataRelevance::getRegionId, DefValConstants.ZJREGION_ID)
                    .eq(BulkCementDirectReportSystemDataRelevance::getAuditType,DataUploadAuditTypeEnum.PROVINCE_AUDIT.getCode())
                    .eq(BulkCementDirectReportSystemDataRelevance::getReportYear, reportYear)
                    .eq(BulkCementDirectReportSystemDataRelevance::getAuditDataType, UploadDataTypeEnum.BULK_CEMENT_LOGISTIC_FACILITY_STATISTIC_ANNUAL_REPORT.getCode()));

            // 如果上报月份省级关联数据不存在
            // 补充省散办关联数据信息
            if (Objects.isNull(provinceData)) {
                BulkCementDirectReportSystemDataRelevance provinceRelevanceData = new BulkCementDirectReportSystemDataRelevance();
                assemblyRelevanceData(userDetail, reportYear, provinceRelevanceData);
                provinceRelevanceData.setAuditInfoId(provinceAuditInfo.getId());
                provinceRelevanceData.setRegionId(DefValConstants.ZJREGION_ID);
                provinceRelevanceData.setAuditType(DataUploadAuditTypeEnum.PROVINCE_AUDIT.getCode());
                // 获取省散装中心所属的管理企业ID
                CompanyDTO companyDto = companiesCacheHelper.getByName(DefValConstants.PROVINCE + VehicleContant.ADMIN_COMPANY_NAME);
                if (Objects.nonNull(companyDto)) {
                    provinceRelevanceData.setCompanyId(companyDto.getId());
                }
                provinceRelevanceData.setAuditDataType(UploadDataTypeEnum.BULK_CEMENT_LOGISTIC_FACILITY_STATISTIC_ANNUAL_REPORT.getCode());
                provinceRelevanceData.setAuditStatus(DataUploadAuditStatusEnum.UNDER_AUDIT.getCode());
                dataRelevanceService.save(provinceRelevanceData);
            }

            // 创建省级审核记录
            BulkCementDirectReportSystemAuditRecord provinceAuditRecord = new BulkCementDirectReportSystemAuditRecord();
            assemblyAuditRecord(userDetail, cityRelevanceData.getId(), provinceAuditInfo.getId(), provinceAuditRecord);
            provinceAuditRecord.setReportYear(cityRelevanceData.getReportYear());
            provinceAuditRecord.setAuditType(DataUploadAuditTypeEnum.PROVINCE_AUDIT.getCode());
            auditRecordService.save(provinceAuditRecord);
        }
        return "上报成功!";
    }

    private void assemblyRelevanceData(UserInfoDetails userDetail, Integer reportYear, BulkCementDirectReportSystemDataRelevance relevanceData) {
        relevanceData.setReportYear(reportYear);
        relevanceData.setCreateOn(LocalDateTime.now());
        relevanceData.setCreateBy(userDetail.getUserId());
        relevanceData.setUpdateOn(LocalDateTime.now());
        relevanceData.setUpdateBy(userDetail.getUserId());
        relevanceData.setLastUpdateTime(LocalDateTime.now());

    }
    private void assemblyAuditRecord(UserInfoDetails userDetail, Long auditDataId, Long auditInfoId, BulkCementDirectReportSystemAuditRecord auditRecord) {
        auditRecord.setAuditDataId(auditDataId);
        auditRecord.setAuditInfoId(auditInfoId);
        auditRecord.setAuditStatus(DataUploadAuditStatusEnum.UNDER_AUDIT.getCode());
        auditRecord.setAuditDataType(UploadDataTypeEnum.BULK_CEMENT_LOGISTIC_FACILITY_STATISTIC_ANNUAL_REPORT.getCode());
        auditRecord.setCompanyId(userDetail.getCompanyId());
        auditRecord.setRegionId(userDetail.getRegionId());
        auditRecord.setCreateOn(LocalDateTime.now());
        auditRecord.setCreateBy(userDetail.getUserId());
        auditRecord.setUpdateOn(LocalDateTime.now());
        auditRecord.setUpdateBy(userDetail.getUserId());
    }

    private void assemblyAuditInfo(BulkCementDirectReportSystemAuditInfo auditInfo, DataUploadAuditStatusEnum underAudit, UserInfoDetails userDetail) {
        auditInfo.setAuditStatus(underAudit.getCode());
        auditInfo.setAuditDataType(UploadDataTypeEnum.BULK_CEMENT_LOGISTIC_FACILITY_STATISTIC_ANNUAL_REPORT.getCode());
        auditInfo.setCreateOn(LocalDateTime.now());
        auditInfo.setCreateBy(userDetail.getUserId());
        auditInfo.setUpdateOn(LocalDateTime.now());
        auditInfo.setUpdateBy(userDetail.getUserId());
    }

    private void assemblyData(ReqBulkCementLogFacStaDataUploadDTO req, UserInfoDetails userDetail, BulkCementLogisticFacilityStatisticAnnualReport bulkCementLogFacStaAnnualReport) {
        RegionDTO regionDto = regionsCacheHelper.getByRegionId(userDetail.getRegionId());
        String regionName = regionDto.getRegionName();
        // 单位名称改成了地区
        bulkCementLogFacStaAnnualReport.setRegionName(regionName);
        bulkCementLogFacStaAnnualReport.setFacilityName(req.getFacilityName());
        bulkCementLogFacStaAnnualReport.setYearBeginNum(req.getYearBeginNum());
        bulkCementLogFacStaAnnualReport.setYearBeginCapacity(req.getYearBeginCapacity());
        bulkCementLogFacStaAnnualReport.setThisYearNewAddNum(req.getThisYearNewAddNum());
        bulkCementLogFacStaAnnualReport.setThisYearNewAddCapacity(req.getThisYearNewAddCapacity());
        bulkCementLogFacStaAnnualReport.setThisYearScrapNum(req.getThisYearScrapNum());
        bulkCementLogFacStaAnnualReport.setThisYearScrapCapacity(req.getThisYearScrapCapacity());
        bulkCementLogFacStaAnnualReport.setYearEndNum(req.getYearEndNum());
        bulkCementLogFacStaAnnualReport.setYearEndCapacity(req.getYearEndCapacity());
        bulkCementLogFacStaAnnualReport.setThisYearWorkAmount(req.getThisYearWorkAmount());
        bulkCementLogFacStaAnnualReport.setReportYear(req.getReportYear());
        bulkCementLogFacStaAnnualReport.setRemark(req.getRemark());
        bulkCementLogFacStaAnnualReport.setCompanyId(userDetail.getCompanyId());
        bulkCementLogFacStaAnnualReport.setUnitResponsiblePerson(req.getUnitResponsiblePerson());
        bulkCementLogFacStaAnnualReport.setPreparer(req.getPreparer());
        bulkCementLogFacStaAnnualReport.setReviewer(req.getReviewer());
        bulkCementLogFacStaAnnualReport.setSubmissionDate(req.getSubmissionDate());
        bulkCementLogFacStaAnnualReport.setRegionId(userDetail.getRegionId());
        bulkCementLogFacStaAnnualReport.setCreateOn(LocalDateTime.now());
        bulkCementLogFacStaAnnualReport.setCreateBy(userDetail.getUserId());
        bulkCementLogFacStaAnnualReport.setUpdateOn(LocalDateTime.now());
        bulkCementLogFacStaAnnualReport.setUpdateBy(userDetail.getUserId());
    }

    private void checkUploadData(Integer reportYear, Long regionId, BulkCementDirectReportSystemDataRelevance cityData) {
        // 查询区县关联数据
        BulkCementDirectReportSystemDataRelevance dataRelevance = dataRelevanceService.getOne(Wrappers.lambdaQuery(BulkCementDirectReportSystemDataRelevance.class)
                .eq(BulkCementDirectReportSystemDataRelevance::getReportYear, reportYear)
                .eq(BulkCementDirectReportSystemDataRelevance::getRegionId, regionId)
                .eq(BulkCementDirectReportSystemDataRelevance::getAuditDataType, UploadDataTypeEnum.BULK_CEMENT_LOGISTIC_FACILITY_STATISTIC_ANNUAL_REPORT.getCode()));
        if (Objects.nonNull(dataRelevance) &&
                DataUploadAuditStatusEnum.AUDIT_PASS.getCode().equals(dataRelevance.getAuditStatus())){
            // 先删除关联的已经保存的各设备名称的数据
            String auditDataIdList = dataRelevance.getAuditDataIdList();
            if (StringUtils.isNotBlank(auditDataIdList)){
                List<Long> idList = Arrays.stream(auditDataIdList.split(StrPool.COMMA)).map(Long::valueOf).collect(Collectors.toList());
                if (CollUtil.isNotEmpty(idList)){
                    bulkCementLogFacStaService.remove(Wrappers.lambdaQuery(BulkCementLogisticFacilityStatisticAnnualReport.class)
                            .in(BulkCementLogisticFacilityStatisticAnnualReport::getId,idList));
                }
            }
            updateCityData(cityData,dataRelevance);
            dataRelevanceService.removeById(dataRelevance);
        }
    }

    private void updateCityData(BulkCementDirectReportSystemDataRelevance cityData, BulkCementDirectReportSystemDataRelevance dataRelevance) {
        if (Objects.nonNull(cityData)) {
            String auditDataIdList = cityData.getAuditDataIdList();
            if (StringUtils.isNotBlank(auditDataIdList)){
                List<Long> idList = Arrays.stream(auditDataIdList.split(StrPool.COMMA)).map(Long::valueOf).collect(Collectors.toList());
                // 将已经存在的该地区该上报年份的数据数据从市级关联表中删除
                idList.remove(dataRelevance.getId());
            }
        }
    }

    public ResBulkCementLogFacStaDataUploadDetailVO getBulkCementLogFacStaUploadData(ReqBulkCementLogFacStaDataUploadDTO req) {
        // 获取填报的数据
        Integer yearBeginNum = req.getYearBeginNum();
        BigDecimal yearBeginCapacity = req.getYearBeginCapacity();
        Integer thisYearNewAddNum = req.getThisYearNewAddNum();
        BigDecimal thisYearNewAddCapacity = req.getThisYearNewAddCapacity();
        BigDecimal thisYearScrapCapacity = req.getThisYearScrapCapacity();
        Integer thisYearScrapNum = req.getThisYearScrapNum();
        BigDecimal thisYearWorkAmount = req.getThisYearWorkAmount();
        String remark = req.getRemark();
        Integer reportYear = req.getReportYear();
        String facilityName = req.getFacilityName();
        VUtils.isTrue(StringUtils.isBlank(facilityName)).throwMessage("请传入设备名称!");

        ResBulkCementLogFacStaDataUploadDetailVO vo = new ResBulkCementLogFacStaDataUploadDetailVO();
        vo.setYearBeginNum(yearBeginNum);
        vo.setYearBeginCapacity(yearBeginCapacity);
        vo.setThisYearNewAddNum(thisYearNewAddNum);
        vo.setThisYearNewAddCapacity(thisYearNewAddCapacity);
        vo.setThisYearScrapCapacity(thisYearScrapCapacity);
        vo.setThisYearScrapNum(thisYearScrapNum);
        vo.setThisYearWorkAmount(thisYearWorkAmount);
        vo.setReportYear(reportYear);
        vo.setRemark(remark);

        // 计算各数据
        // 年末数量: 年初数量 + 本年新增数量 - 本年报废数量
        if (Objects.nonNull(yearBeginNum) && Objects.nonNull(thisYearNewAddNum) && Objects.nonNull(thisYearScrapNum)){
            int yearEndNum = yearBeginNum + thisYearNewAddNum - thisYearScrapNum;
            vo.setYearEndNum(yearEndNum);
        }
        // 年末容量: 年初容量 + 本年新增容量 - 本年报废容量
        if (Objects.nonNull(yearBeginCapacity) && Objects.nonNull(thisYearNewAddCapacity) && Objects.nonNull(thisYearScrapCapacity)){
            BigDecimal yearEndCapacity = yearBeginCapacity.add(thisYearNewAddCapacity).subtract(thisYearScrapCapacity);
            vo.setYearEndCapacity(yearEndCapacity);
        }
        return vo;
    }

    public ResBulkCementLogFacStaRelatedDataVO getBulkCementLogFacStaRelatedData(ReqBulkCementLogFacStaDataUploadDTO dto) {
        Integer reportYear = dto.getReportYear();
        VUtils.isTrue(Objects.isNull(reportYear)).throwMessage("请传入上报年份!");
        Long regionId = dto.getRegionId();
        VUtils.isTrue(Objects.isNull(regionId)).throwMessage("请传入区域ID!");
        String facilityName = dto.getFacilityName();
        VUtils.isTrue(StringUtils.isBlank(facilityName)).throwMessage("请传入设备名称!");
        Integer preReportYear = reportYear - 1;
        BulkCementLogisticFacilityStatisticAnnualReport preYearBulkCementLogFacStaAnnualReport = bulkCementLogFacStaService.getOne(Wrappers.lambdaQuery(BulkCementLogisticFacilityStatisticAnnualReport.class)
                .eq(BulkCementLogisticFacilityStatisticAnnualReport::getReportYear, preReportYear)
                .eq(BulkCementLogisticFacilityStatisticAnnualReport::getFacilityName,facilityName)
                .eq(BulkCementLogisticFacilityStatisticAnnualReport::getRegionId, regionId));
        ResBulkCementLogFacStaRelatedDataVO vo = new ResBulkCementLogFacStaRelatedDataVO();
        if (Objects.nonNull(preYearBulkCementLogFacStaAnnualReport)) {
            // 去年的年末数量
            vo.setYearBeginNum(preYearBulkCementLogFacStaAnnualReport.getYearEndNum());
            // 去年的年末容量
            vo.setYearBeginCapacity(preYearBulkCementLogFacStaAnnualReport.getYearEndCapacity());
        }
        return vo;
    }
}
