package com.ningdatech.carapi.analysis.manage;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
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.carapi.analysis.entity.WarnAnalysisCar;
import com.ningdatech.carapi.analysis.entity.WarnAnalysisCompany;
import com.ningdatech.carapi.analysis.entity.WarnAnalysisDriver;
import com.ningdatech.carapi.analysis.entity.req.WarnAnalysisListReq;
import com.ningdatech.carapi.analysis.entity.vo.WarnAnalysisByCarVo;
import com.ningdatech.carapi.analysis.entity.vo.WarnAnalysisByCompanyVo;
import com.ningdatech.carapi.analysis.entity.vo.WarnAnalysisByDriverVo;
import com.ningdatech.carapi.analysis.mapper.WarnAnalysisCarMapper;
import com.ningdatech.carapi.analysis.service.IWarnAnalysisCarService;
import com.ningdatech.carapi.analysis.service.IWarnAnalysisCompanyService;
import com.ningdatech.carapi.analysis.service.IWarnAnalysisDriverService;
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.helper.RegionsCacheHelper;
import lombok.RequiredArgsConstructor;
import org.springframework.aop.framework.AopContext;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * WarnAnalysisManage
 * </p>
 *
 * @author WendyYang
 * @since 16:34 2022/10/14
 */
@Component
@RequiredArgsConstructor
public class WarnAnalysisManage {

    private final IWarnAnalysisCarService warnAnalysisCarService;
    private final IWarnAnalysisCompanyService warnAnalysisCompanyService;
    private final RegionsCacheHelper regionsCacheHelper;
    private final IWarnAnalysisDriverService warnAnalysisDriverService;

    private final WarnAnalysisCarMapper warnAnalysisCarMapper;

    /**
     * 车辆综合预警分析列表
     */
    public PageVo<WarnAnalysisByCarVo> listCarWarnAnalysis(WarnAnalysisListReq req) {
        LambdaQueryWrapper<WarnAnalysisCar> query = Wrappers.lambdaQuery(WarnAnalysisCar.class);
        WarnAnalysisManage context = (WarnAnalysisManage) AopContext.currentProxy();
        context.buildCarWarnAnalysisQuery(query, req);
        Page<WarnAnalysisCar> page = warnAnalysisCarService.page(req.page(), query);
        if (0L == page.getTotal()) {
            return PageVo.empty();
        }
        List<WarnAnalysisByCarVo> res = page.getRecords().stream().map(w -> {
            WarnAnalysisByCarVo vo = BeanUtil.copyProperties(w, WarnAnalysisByCarVo.class);
            if (Objects.nonNull(w.getRegionId())) {
                vo.setRegions(regionsCacheHelper.listParents(w.getRegionId()));
            }
            CodeUtil.searchCompanyName(vo);
            return vo;
        }).collect(Collectors.toList());
        return PageVo.of(res, page.getTotal());
    }

    @LambdaDataScope
    @BuildChildrenRegionWrapper
    public void buildCarWarnAnalysisQuery(LambdaQueryWrapper<WarnAnalysisCar> query, WarnAnalysisListReq req) {
        query.like(StrUtil.isNotBlank(req.getCarNo()), WarnAnalysisCar::getCarNo, req.getCarNo())
                .like(StrUtil.isNotBlank(req.getCompanyName()), WarnAnalysisCar::getCompanyName, req.getCompanyName())
                .eq(Objects.nonNull(req.getDangerLevel()), WarnAnalysisCar::getDangerLevel, req.getDangerLevel())
                .orderByDesc(WarnAnalysisCar::getDangerScore)
                .orderByDesc(WarnAnalysisCar::getUpdateOn);
    }

    /**
     * 企业综合预警分析列表
     */
    public PageVo<WarnAnalysisByCompanyVo> listCompanyWarnAnalysis(WarnAnalysisListReq req) {
        String companyName = req.getCompanyName();
        Integer carCount = warnAnalysisCarMapper.selectVehiclesNum(companyName);
        LambdaQueryWrapper<WarnAnalysisCompany> query = Wrappers.lambdaQuery(WarnAnalysisCompany.class);
        WarnAnalysisManage context = (WarnAnalysisManage) AopContext.currentProxy();
        context.buildCompanyWarnAnalysisQuery(query, req);
        Page<WarnAnalysisCompany> page = warnAnalysisCompanyService.page(req.page(), query);
        if (0L == page.getTotal()) {
            return PageVo.empty();
        }
        List<WarnAnalysisByCompanyVo> res = page.getRecords().stream().map(w -> {
            WarnAnalysisByCompanyVo vo = BeanUtil.copyProperties(w, WarnAnalysisByCompanyVo.class);
            if  (Objects.nonNull(w.getRegionId())) {
                vo.setRegions(regionsCacheHelper.listParents(w.getRegionId()));
            }
            vo.setCarCount(carCount);
            CodeUtil.searchCompanyName(vo);
            return vo;
        }).collect(Collectors.toList());
        return PageVo.of(res, page.getTotal());
    }

    @LambdaDataScope
    @BuildChildrenRegionWrapper
    public void buildCompanyWarnAnalysisQuery(LambdaQueryWrapper<WarnAnalysisCompany> query, WarnAnalysisListReq req) {
        query.like(StrUtil.isNotBlank(req.getCompanyName()), WarnAnalysisCompany::getCompanyName, req.getCompanyName())
                .eq(Objects.nonNull(req.getDangerLevel()), WarnAnalysisCompany::getDangerLevel, req.getDangerLevel())
                .orderByDesc(WarnAnalysisCompany::getTotalScore)
                .orderByDesc(WarnAnalysisCompany::getUpdateOn);
    }

    /**
     * 驾驶员综合预警分析列表
     */
    public PageVo<WarnAnalysisByDriverVo> listDriverWarnAnalysis(WarnAnalysisListReq req) {
        LambdaQueryWrapper<WarnAnalysisDriver> query = Wrappers.lambdaQuery(WarnAnalysisDriver.class);
        WarnAnalysisManage context = (WarnAnalysisManage) AopContext.currentProxy();
        context.buildDriverWarnAnalysisQuery(query, req);
        Page<WarnAnalysisDriver> page = warnAnalysisDriverService.page(req.page(), query);
        if (0L == page.getTotal()) {
            return PageVo.empty();
        }
        List<WarnAnalysisByDriverVo> res = page.getRecords().stream().map(w -> {
            WarnAnalysisByDriverVo vo = BeanUtil.copyProperties(w, WarnAnalysisByDriverVo.class);
            if (Objects.nonNull(w.getRegionId())) {
                vo.setRegions(regionsCacheHelper.listParents(w.getRegionId()));
            }
            CodeUtil.searchCompanyName(vo);
            return vo;
        }).collect(Collectors.toList());
        return PageVo.of(res, page.getTotal());
    }

    @LambdaDataScope
    @BuildChildrenRegionWrapper
    public void buildDriverWarnAnalysisQuery(LambdaQueryWrapper<WarnAnalysisDriver> query, WarnAnalysisListReq req) {
        query.eq(StrUtil.isNotBlank(req.getDriverName()), WarnAnalysisDriver::getDriverName, req.getDriverName())
                .like(StrUtil.isNotBlank(req.getCompanyName()), WarnAnalysisDriver::getCompanyName, req.getCompanyName())
                .eq(Objects.nonNull(req.getDangerLevel()), WarnAnalysisDriver::getDangerLevel, req.getDangerLevel())
                .orderByDesc(WarnAnalysisDriver::getDangerScore)
                .orderByDesc(WarnAnalysisDriver::getUpdateOn);
    }

}
