package com.ningdatech.carapi.company.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ningdatech.carapi.car.datascreen.model.dto.DataScreenParam;
import com.ningdatech.carapi.common.aop.BuildChildrenRegionWrapper;
import com.ningdatech.carapi.company.entity.NdCompanyQualityManage;
import com.ningdatech.carapi.company.entity.dto.ResCompanyTotalDTO;
import com.ningdatech.carapi.company.entity.po.ResCompanyTotalPO;
import com.ningdatech.carapi.company.service.ICompanyLargeScreenService;
import com.ningdatech.carapi.company.service.INdCompanyQualityManageService;
import com.ningdatech.carapi.datascope.aop.LambdaDataScope;
import com.ningdatech.carapi.industry.service.IReadyMixedMortarIndustryManageService;
import com.ningdatech.carapi.safe.entity.NdVehicleAccidentDead;
import com.ningdatech.carapi.safe.service.INdVehicleAccidentDeadService;
import com.ningdatech.carapi.sys.helper.CompaniesCacheHelper;
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.beans.BeanUtils;
import org.springframework.stereotype.Service;

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

/**
 * @description: 大屏管理
 * @author: liushuai
 * @date: 2022/10/25 10:14
 */
@Service
@RequiredArgsConstructor
public class CompanyLargeScreenServiceImpl implements ICompanyLargeScreenService {
    private final INdVehicleAccidentDeadService accidentDeadService;
    private final CompanyService companyService;
    private final CompaniesCacheHelper companiesCacheHelper;
    private final IReadyMixedMortarIndustryManageService mortarQualityService;

    private final INdCompanyQualityManageService iNdCompanyQualityManageService;

    @Override
    public List<ResCompanyTotalDTO> getCompanyTotalByRegionId(Long regionId) {
        DataScreenParam param = new DataScreenParam();
        param.setRegionId(regionId);
        List<ResCompanyTotalPO> resCompanyTotalList = companyService.countByRegion(param);
        if (CollUtil.isEmpty(resCompanyTotalList)) {
            return Collections.emptyList();
        }
        return resCompanyTotalList.stream().map(w -> {
            ResCompanyTotalDTO dto = new ResCompanyTotalDTO();
            BeanUtils.copyProperties(w, dto);
            return dto;
        }).collect(Collectors.toList());
    }

    @Override
    public List<ResCompanyTotalDTO> countEnterpriseType(Long regionId) {
        DataScreenParam param = new DataScreenParam();
        param.setRegionId(regionId);
        List<ResCompanyTotalPO> resCompanyTotalList = companyService.countEnterpriseType(param);
        if (CollUtil.isEmpty(resCompanyTotalList)) {
            return Collections.emptyList();
        }
        return resCompanyTotalList.stream().map(w -> {
            ResCompanyTotalDTO dto = new ResCompanyTotalDTO();
            BeanUtils.copyProperties(w, dto);
            return dto;
        }).collect(Collectors.toList());
    }

    @Override
    public List<ResCompanyTotalDTO> deadAccident(Long regionId) {
        DataScreenParam param = new DataScreenParam();
        param.setRegionId(regionId);
        param.setStartTime(LocalDateTime.now().minusMonths(6));
        //半年内
        param.setEndTime(LocalDateTime.now());

        LambdaQueryWrapper<NdVehicleAccidentDead> wrapper = Wrappers.lambdaQuery(NdVehicleAccidentDead.class);
        List<NdVehicleAccidentDead> accidentDeadList = ((CompanyLargeScreenServiceImpl) AopContext.currentProxy()).countDeadCompany(wrapper, param);

        if (CollUtil.isEmpty(accidentDeadList)) {
            return Collections.emptyList();
        }
        return accidentDeadList.stream().filter(w -> {
                    if (w.getCompanyId() == null) {
                        return false;
                    }
                    String companyName = companiesCacheHelper.getNameById(w.getCompanyId());
                    boolean notBlank = StrUtil.isNotBlank(companyName);
                    if (notBlank) {
                        w.setCompanyName(companyName);
                    }
                    return notBlank;
                }).map(w -> ResCompanyTotalDTO.builder().name(w.getCompanyName()).build())
                .collect(Collectors.toList());
    }

    @Override
    public List<ResCompanyTotalDTO> mortarQuality(Long regionId) {
        DataScreenParam param = new DataScreenParam();
        param.setRegionId(regionId);
        LambdaQueryWrapper<NdCompanyQualityManage> wrapper = Wrappers.lambdaQuery(NdCompanyQualityManage.class);
        List<NdCompanyQualityManage> list = ((CompanyLargeScreenServiceImpl) AopContext.currentProxy()).mortarQualityies(wrapper, param);

        if (CollUtil.isEmpty(list)) {
            return Collections.emptyList();
        }
        return list.stream().map(w -> {
            ResCompanyTotalDTO dto = new ResCompanyTotalDTO();
            dto.setFileId(StringUtils.isNotBlank(w.getFilePath()) ?
                    Long.parseLong(w.getFilePath()) : null);
            dto.setName(w.getFileName());
            return dto;
        }).collect(Collectors.toList());
    }

    @LambdaDataScope
    @BuildChildrenRegionWrapper
    public List<NdCompanyQualityManage> mortarQualityies(LambdaQueryWrapper<NdCompanyQualityManage> wrapper, DataScreenParam param) {
        return iNdCompanyQualityManageService.list(wrapper
                .orderBy(Boolean.TRUE, Boolean.FALSE, NdCompanyQualityManage::getUpdateOn));
    }

    @LambdaDataScope
    @BuildChildrenRegionWrapper
    public List<NdVehicleAccidentDead> countDeadCompany(LambdaQueryWrapper<NdVehicleAccidentDead> wrapper, DataScreenParam param) {
        wrapper.select(NdVehicleAccidentDead::getCompanyId)
                .ge(Objects.nonNull(param.getStartTime()), NdVehicleAccidentDead::getAccidentTime, param.getStartTime())
                .le(Objects.nonNull(param.getEndTime()), NdVehicleAccidentDead::getAccidentTime, param.getEndTime())
                .groupBy(NdVehicleAccidentDead::getCompanyId);
        return accidentDeadService.list(wrapper);
    }
}
