package com.ningdatech.carapi.safe.manage;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
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.PageVo;
import com.ningdatech.basic.util.CollUtils;
import com.ningdatech.carapi.common.aop.BuildChildrenRegionWrapper;
import com.ningdatech.carapi.common.util.CodeUtil;
import com.ningdatech.carapi.company.entity.CompanySecurityCommitment;
import com.ningdatech.carapi.company.service.ICompanySecurityCommitmentService;
import com.ningdatech.carapi.datascope.aop.LambdaDataScope;
import com.ningdatech.carapi.safe.constant.SecurityContant;
import com.ningdatech.carapi.safe.entity.NdSafetyCommitment;
import com.ningdatech.carapi.safe.entity.NdSafetyCredit;
import com.ningdatech.carapi.safe.model.dto.SecurityHonestyPageQuery;
import com.ningdatech.carapi.safe.model.vo.NdSafetyCommitmentVO;
import com.ningdatech.carapi.safe.model.vo.NdSafetyCreditVO;
import com.ningdatech.carapi.safe.service.INdSafetyCommitmentService;
import com.ningdatech.carapi.safe.service.INdSafetyCreditService;
import com.ningdatech.carapi.sys.entity.Company;
import com.ningdatech.carapi.sys.manage.CompanyManage;
import com.ningdatech.carapi.sys.service.CompanyService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.aop.framework.AopContext;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author CMM
 * @description SecurityHonestyManage
 * @since 2022/11/16 16:00
 */
@Component
@RequiredArgsConstructor
public class SecurityHonestyManage {
    private final INdSafetyCommitmentService safetyCommitmentService;
    private final INdSafetyCreditService safetyCreditService;

    private final CompanyService companyService;

    private final ICompanySecurityCommitmentService commitmentService;

    public PageVo<NdSafetyCommitmentVO> queryCommitment(SecurityHonestyPageQuery param) {
        Page<Company> page = param.page();
        LambdaQueryWrapper<Company> wrapper = Wrappers.lambdaQuery(Company.class)
                .ne(Company::getCompanyType,0);
        companyService.pageDataScope(page,wrapper,param);
        if(0L == page.getTotal()){
            return PageVo.empty();
        }

        List<Long> companyIds = page.getRecords().stream().map(Company::getId).collect(Collectors.toList());
        //去查出 安全承诺 列表
        List<CompanySecurityCommitment>  commitments = commitmentService.list(Wrappers.lambdaQuery(CompanySecurityCommitment.class)
                .in(CompanySecurityCommitment::getCompanyId,companyIds));
        //分组 map
        Map<Long, List<CompanySecurityCommitment>> dataMap = commitments.stream().collect(Collectors.groupingBy(CompanySecurityCommitment::getCompanyId));

        final Long[] index = {1L};
        List<NdSafetyCommitmentVO> data = CollUtils.convert(page.getRecords(), e -> {
            NdSafetyCommitmentVO vo = BeanUtil.copyProperties(e, NdSafetyCommitmentVO.class);
            vo.setId(index[0]);
            vo.setCompanyId(e.getId());
            vo.setCompanyAddress(e.getAddress());
            CodeUtil.searchCompanyNameAndRegionName(vo);
            countCommitment(vo,dataMap.get(e.getId()));
            index[0]++;
            return vo;
        });
        return PageVo.of(data, page.getTotal());
    }

    //统计 安全承诺数
    private void countCommitment(NdSafetyCommitmentVO vo, List<CompanySecurityCommitment> companySecurityCommitments) {
        if(CollUtil.isEmpty(companySecurityCommitments)){
            return;
        }
        //向社会承诺
        Integer commitmentsToSocial = 0;
        //向员工承诺
        Integer commitmentsToEmployee = 0;
        //总经理承诺
        Integer generalManagercommitment = 0;
        //分管总承诺
        Integer leaderInChargeCommitment = 0;
        //车队长承诺
        Integer teamLeaderCommitment = 0;
        //驾驶员承诺
        Integer driverCommitment = 0;
        for(CompanySecurityCommitment commitment : companySecurityCommitments){
            if(SecurityContant.Commitment.COMMITMENT_SOCIAL.equals(
                    commitment.getCommitmentTarget())){
                commitmentsToSocial++;
            }else if(SecurityContant.Commitment.COMMITMENT_EMPLOYEE.equals(
                    commitment.getCommitmentTarget())){
                commitmentsToEmployee++;
            }else if(SecurityContant.Commitment.COMMITMENT_GENERAL.equals(
                    commitment.getPromisee())){
                generalManagercommitment++;
            }else if(SecurityContant.Commitment.COMMITMENT_LEADER.equals(
                    commitment.getPromisee())){
                leaderInChargeCommitment++;
            }else if(SecurityContant.Commitment.COMMITMENT_TEAMLEADER.equals(
                    commitment.getPromisee())){
                teamLeaderCommitment++;
            }else if(SecurityContant.Commitment.COMMITMENT_DRIVER.equals(
                    commitment.getPromisee())){
                driverCommitment++;
            }
        }
        vo.setCommitmentsToSocial(commitmentsToSocial);
        vo.setCommitmentsToEmployee(commitmentsToEmployee);
        vo.setGeneralManagercommitment(generalManagercommitment);
        vo.setLeaderInChargeCommitment(leaderInChargeCommitment);
        vo.setDriverCommitment(driverCommitment);
        vo.setTeamLeaderCommitment(teamLeaderCommitment);
    }

    public void buildCommitmentWrapper(Page<NdSafetyCommitment> page, SecurityHonestyPageQuery securityAdvisoryPageQuery) {
        LambdaQueryWrapper<NdSafetyCommitment> wrapper = Wrappers.lambdaQuery(NdSafetyCommitment.class);
        SecurityHonestyManage context = (SecurityHonestyManage)AopContext.currentProxy();
        context.searchCommitment(page,wrapper,securityAdvisoryPageQuery);
    }

    @LambdaDataScope(wrapperIndex = 1)
    @BuildChildrenRegionWrapper(entityIndex = 2,wrapperIndex = 1)
    public void searchCommitment(Page<NdSafetyCommitment> page, LambdaQueryWrapper<NdSafetyCommitment> wrapper, SecurityHonestyPageQuery securityAdvisoryPageQuery) {
        wrapper.like(StringUtils.isNotBlank(securityAdvisoryPageQuery.getCompanyName()),NdSafetyCommitment::getCompanyName,securityAdvisoryPageQuery.getCompanyName());
        wrapper.orderBy(Boolean.TRUE,Boolean.FALSE,NdSafetyCommitment::getUpdateOn);
        safetyCommitmentService.page(page, wrapper);
    }

    public PageVo<NdSafetyCreditVO> queryCredit(SecurityHonestyPageQuery securityAdvisoryPageQuery) {
        Page<NdSafetyCredit> page = securityAdvisoryPageQuery.page();
        buildCreditWrapper(page, securityAdvisoryPageQuery);
        List<NdSafetyCreditVO> data = CollUtils.convert(page.getRecords(), e -> {
            NdSafetyCreditVO vo = BeanUtil.copyProperties(e, NdSafetyCreditVO.class);
            CodeUtil.searchCompanyNameAndRegionName(vo);
            return vo;
        });
        return PageVo.of(data, page.getTotal());
    }

    public void buildCreditWrapper(Page<NdSafetyCredit> page, SecurityHonestyPageQuery securityAdvisoryPageQuery) {
        LambdaQueryWrapper<NdSafetyCredit> wrapper = Wrappers.lambdaQuery(NdSafetyCredit.class);
        SecurityHonestyManage context = (SecurityHonestyManage)AopContext.currentProxy();
        context.searchCredit(page, wrapper, securityAdvisoryPageQuery);
    }

    @LambdaDataScope(wrapperIndex = 1)
    @BuildChildrenRegionWrapper(entityIndex = 2,wrapperIndex = 1)
    public void searchCredit(Page<NdSafetyCredit> page, LambdaQueryWrapper<NdSafetyCredit> wrapper, SecurityHonestyPageQuery securityAdvisoryPageQuery) {
        wrapper.like(StringUtils.isNotBlank(securityAdvisoryPageQuery.getCompanyName()),NdSafetyCredit::getCompanyName,securityAdvisoryPageQuery.getCompanyName());
        wrapper.orderBy(Boolean.TRUE,Boolean.FALSE,NdSafetyCredit::getUpdateOn);
        safetyCreditService.page(page, wrapper);
    }
}
