package com.ningdatech.carapi.analysis.manage;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ningdatech.basic.model.IdVo;
import com.ningdatech.basic.model.PageVo;
import com.ningdatech.carapi.analysis.entity.SecurityManageGrade;
import com.ningdatech.carapi.analysis.entity.SecurityManageResultEval;
import com.ningdatech.carapi.analysis.entity.SecurityRiskEval;
import com.ningdatech.carapi.analysis.entity.SecuritySystemBuildingEval;
import com.ningdatech.carapi.analysis.entity.req.SecurityManageGradeListReq;
import com.ningdatech.carapi.analysis.entity.req.SecurityRiskEvalListReq;
import com.ningdatech.carapi.analysis.entity.req.SecurityRiskEvalSaveReq;
import com.ningdatech.carapi.analysis.entity.req.SecuritySystemBuildingEvalSaveReq;
import com.ningdatech.carapi.analysis.entity.vo.SecurityManageGradeVo;
import com.ningdatech.carapi.analysis.entity.vo.SecurityManageResultEvalListVo;
import com.ningdatech.carapi.analysis.entity.vo.SecurityRiskEvalListVo;
import com.ningdatech.carapi.analysis.entity.vo.SecuritySystemBuildingEvalListVo;
import com.ningdatech.carapi.analysis.service.ISecurityManageGradeService;
import com.ningdatech.carapi.analysis.service.ISecurityManageResultEvalService;
import com.ningdatech.carapi.analysis.service.ISecurityRiskEvalService;
import com.ningdatech.carapi.analysis.service.ISecuritySystemBuildingEvalService;
import com.ningdatech.carapi.common.aop.BuildChildrenRegionWrapper;
import com.ningdatech.carapi.common.util.CodeUtil;
import com.ningdatech.carapi.datascope.aop.LambdaDataScope;
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.util.LoginUserUtil;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.aop.framework.AopContext;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * SecurityAnalysisEvalManage
 * </p>
 *
 * @author WendyYang
 * @since 14:47 2022/10/13
 */
@Component
@RequiredArgsConstructor
public class SecurityAnalysisEvalManage {

    private final RegionsCacheHelper regionsCacheHelper;
    private final CompaniesCacheHelper companiesCacheHelper;
    private final ISecurityManageGradeService securityManagementGradeService;
    private final ISecurityRiskEvalService securityRiskEvaluationService;
    private final ISecuritySystemBuildingEvalService systemBuildingEvalService;
    private final ISecurityManageResultEvalService securityManageResultEvalService;

    /**
     * 安全管理综合评级列表
     **/
    public PageVo<SecurityManageGradeVo> list(SecurityManageGradeListReq req) {
        LambdaQueryWrapper<SecurityManageGrade> query = Wrappers.lambdaQuery(SecurityManageGrade.class);
        SecurityAnalysisEvalManage context = (SecurityAnalysisEvalManage) AopContext.currentProxy();
        context.buildSecurityManageGradeQuery(query,req);
        Page<SecurityManageGrade> page = securityManagementGradeService.page(req.page(), query);
        if (0L == page.getTotal()) {
            return PageVo.empty();
        }
        List<SecurityManageGradeVo> res = page.getRecords().stream().map(w -> {
            SecurityManageGradeVo gradeVo = BeanUtil.copyProperties(w, SecurityManageGradeVo.class);
            List<RegionDTO> regions = regionsCacheHelper.listParents(w.getRegionId());
            gradeVo.setRegions(regions);
            CodeUtil.searchCompanyName(gradeVo);
            return gradeVo;
        }).collect(Collectors.toList());
        return PageVo.of(res, page.getTotal());
    }
    @LambdaDataScope
    @BuildChildrenRegionWrapper
    public void buildSecurityManageGradeQuery(LambdaQueryWrapper<SecurityManageGrade> query,SecurityManageGradeListReq req) {
        if (StringUtils.isNotBlank(req.getCompanyName())) {
            query.like(SecurityManageGrade::getCompanyName, req.getCompanyName());
        }
        if (StringUtils.isNotBlank(req.getSecurityLevel())) {
            query.eq(SecurityManageGrade::getSecurityLevel, req.getSecurityLevel());
        }
        if (req.getYear() != null) {
            query.eq(SecurityManageGrade::getYear, req.getYear());
        }
        query.orderByDesc(SecurityManageGrade::getId);
    }

    /**
     * 安全责任体系分析评估列表
     */
    public PageVo<SecurityRiskEvalListVo> list(SecurityRiskEvalListReq req) {
        LambdaQueryWrapper<SecurityRiskEval> query = Wrappers.lambdaQuery(SecurityRiskEval.class);
        SecurityAnalysisEvalManage context = (SecurityAnalysisEvalManage) AopContext.currentProxy();
        context.buildSecurityRiskEvalQuery(query, req);
        Page<SecurityRiskEval> page = securityRiskEvaluationService.page(req.page(), query);
        if (0L == page.getTotal()) {
            return PageVo.empty();
        }
        List<SecurityRiskEvalListVo> res = page.getRecords().stream().map(w -> {
            SecurityRiskEvalListVo gradeVo = BeanUtil.copyProperties(w, SecurityRiskEvalListVo.class);
            List<RegionDTO> regions = regionsCacheHelper.listParents(w.getRegionId());
            gradeVo.setRegions(regions);
            CodeUtil.searchCompanyName(gradeVo);
            return gradeVo;
        }).collect(Collectors.toList());
        return PageVo.of(res, page.getTotal());
    }
    @LambdaDataScope
    @BuildChildrenRegionWrapper
    public void buildSecurityRiskEvalQuery(LambdaQueryWrapper<SecurityRiskEval> query, SecurityRiskEvalListReq req) {
        if (StringUtils.isNotBlank(req.getCompanyName())) {
            query.like(SecurityRiskEval::getCompanyName, req.getCompanyName());
        }
        if (req.getScoreRanges() != null) {
            Pair<Integer, Integer> ranges = req.getScoreRanges();
            query.ge(ranges.getLeft() != null, SecurityRiskEval::getTotalScore, ranges.getLeft());
            query.le(ranges.getRight() != null, SecurityRiskEval::getTotalScore, ranges.getRight());
        }
        if (req.getYear() != null) {
            query.eq(SecurityRiskEval::getYear, req.getYear());
        }
        query.orderByDesc(SecurityRiskEval::getId);
    }

    /**
     * 安全制度建设分析评估列表
     */
    public PageVo<SecuritySystemBuildingEvalListVo> listSystemBuildingEval(SecurityRiskEvalListReq req) {
        LambdaQueryWrapper<SecuritySystemBuildingEval> query = Wrappers.lambdaQuery(SecuritySystemBuildingEval.class);
        SecurityAnalysisEvalManage context = (SecurityAnalysisEvalManage) AopContext.currentProxy();
        context.buildSystemBuildingEvalQuery(query, req);
        Page<SecuritySystemBuildingEval> page = systemBuildingEvalService.page(req.page(), query);
        if (0L == page.getTotal()) {
            return PageVo.empty();
        }
        List<SecuritySystemBuildingEvalListVo> res = page.getRecords().stream().map(w -> {
            SecuritySystemBuildingEvalListVo gradeVo = BeanUtil.copyProperties(w, SecuritySystemBuildingEvalListVo.class);
            List<RegionDTO> regions = regionsCacheHelper.listParents(w.getRegionId());
            gradeVo.setRegions(regions);
            CodeUtil.searchCompanyName(gradeVo);
            return gradeVo;
        }).collect(Collectors.toList());
        return PageVo.of(res, page.getTotal());
    }
    @LambdaDataScope
    @BuildChildrenRegionWrapper
    public void buildSystemBuildingEvalQuery(LambdaQueryWrapper<SecuritySystemBuildingEval> query, SecurityRiskEvalListReq req) {
        if (StringUtils.isNotBlank(req.getCompanyName())) {
            query.like(SecuritySystemBuildingEval::getCompanyName, req.getCompanyName());
        }
        if (req.getScoreRanges() != null) {
            Pair<Integer, Integer> ranges = req.getScoreRanges();
            query.ge(ranges.getLeft() != null, SecuritySystemBuildingEval::getTotalScore, ranges.getLeft());
            query.le(ranges.getRight() != null, SecuritySystemBuildingEval::getTotalScore, ranges.getRight());
        }
        if (req.getYear() != null) {
            query.eq(SecuritySystemBuildingEval::getYear, req.getYear());
        }
        query.orderByDesc(SecuritySystemBuildingEval::getId);
    }

    /**
     * 新增安全责任体系评估
     */

    public IdVo<Integer> save(SecurityRiskEvalSaveReq req) {
        Assert.isTrue(0L == securityRiskEvaluationService.count(Wrappers.lambdaQuery(SecurityRiskEval.class)
                .eq(SecurityRiskEval::getYear, req.getYear())
                .eq(SecurityRiskEval::getCompanyId, req.getCompanyId())), "已存在该年度安全责任体系评估");
        CompanyDTO company = companiesCacheHelper.getById(req.getCompanyId());
        SecurityRiskEval insert = BeanUtil.copyProperties(req, SecurityRiskEval.class);
        insert.setCreateBy(LoginUserUtil.getUserId());
        insert.setCreateOn(LocalDateTime.now());
        insert.setRegionId(company.getRegionId());
        insert.setUpdateBy(insert.getCreateBy());
        insert.setUpdateOn(insert.getCreateOn());
        securityRiskEvaluationService.save(insert);
        return IdVo.of(insert.getId());
    }

    /**
     * 新增安全制度建设分析评估
     */
    public IdVo<Integer> save(SecuritySystemBuildingEvalSaveReq req) {
        Assert.isTrue(0L == systemBuildingEvalService.count(Wrappers.lambdaQuery(SecuritySystemBuildingEval.class)
                .eq(SecuritySystemBuildingEval::getYear, req.getYear())
                .eq(SecuritySystemBuildingEval::getCompanyId, req.getCompanyId())), "已存在该年度安全制度建设评估");
        CompanyDTO company = companiesCacheHelper.getById(req.getCompanyId());
        SecuritySystemBuildingEval insert = BeanUtil.copyProperties(req, SecuritySystemBuildingEval.class);
        insert.setCreateBy(LoginUserUtil.getUserId());
        insert.setCreateOn(LocalDateTime.now());
        insert.setRegionId(company.getRegionId());
        insert.setUpdateBy(insert.getCreateBy());
        insert.setUpdateOn(insert.getCreateOn());
        systemBuildingEvalService.save(insert);
        return IdVo.of(insert.getId());
    }
    /**
     * 安全管理结果分析评估列表
     */
    public PageVo<SecurityManageResultEvalListVo> listSecurityManageResultEval(SecurityRiskEvalListReq req) {
        LambdaQueryWrapper<SecurityManageResultEval> query = Wrappers.lambdaQuery(SecurityManageResultEval.class);
        SecurityAnalysisEvalManage context = (SecurityAnalysisEvalManage) AopContext.currentProxy();
        context.buildSecurityManageResultEvalQuery(query, req);
        Page<SecurityManageResultEval> page = securityManageResultEvalService.page(req.page(), query);
        if (0L == page.getTotal()) {
            return PageVo.empty();
        }
        List<SecurityManageResultEvalListVo> res = page.getRecords().stream().map(w -> {
            SecurityManageResultEvalListVo gradeVo = BeanUtil.copyProperties(w, SecurityManageResultEvalListVo.class);
            List<RegionDTO> regions = regionsCacheHelper.listParents(w.getRegionId());
            gradeVo.setRegions(regions);
            CodeUtil.searchCompanyName(gradeVo);
            return gradeVo;
        }).collect(Collectors.toList());
        return PageVo.of(res, page.getTotal());
    }
    @LambdaDataScope
    @BuildChildrenRegionWrapper
    public void buildSecurityManageResultEvalQuery(LambdaQueryWrapper<SecurityManageResultEval> query, SecurityRiskEvalListReq req) {
        if (StringUtils.isNotBlank(req.getCompanyName())) {
            query.like(SecurityManageResultEval::getCompanyName, req.getCompanyName());
        }
        if (req.getScoreRanges() != null) {
            Pair<Integer, Integer> ranges = req.getScoreRanges();
            query.ge(ranges.getLeft() != null, SecurityManageResultEval::getTotalScore, ranges.getLeft());
            query.le(ranges.getRight() != null, SecurityManageResultEval::getTotalScore, ranges.getRight());
        }
        if (req.getYear() != null) {
            query.eq(SecurityManageResultEval::getYear, req.getYear());
        }
        query.orderByDesc(SecurityManageResultEval::getId);
    }

}
