package com.ningdatech.carapi.car.rpt.manage;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.excel.EasyExcel;
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.car.rpt.entity.*;
import com.ningdatech.carapi.car.rpt.model.dto.RptOtherParamDTO;
import com.ningdatech.carapi.car.rpt.model.po.RptOtherAlarmCleanVehiclesPO;
import com.ningdatech.carapi.car.rpt.model.po.RptOtherCrossDomainVehiclesPO;
import com.ningdatech.carapi.car.rpt.model.po.RptOtherOnlineVehiclesPO;
import com.ningdatech.carapi.car.rpt.model.po.RptOtherSpecialOverspeedPO;
import com.ningdatech.carapi.car.rpt.model.vo.*;
import com.ningdatech.carapi.car.rpt.service.*;
import com.ningdatech.carapi.car.trips.manage.VehicleTripsManage;
import com.ningdatech.carapi.car.trips.model.dto.VehicleTripsParamDTO;
import com.ningdatech.carapi.car.trips.model.vo.VehicleTripsCityVO;
import com.ningdatech.carapi.car.trips.model.vo.VehicleTripsCompanyVO;
import com.ningdatech.carapi.common.util.CodeUtil;
import com.ningdatech.carapi.common.util.ExcelDownUtil;
import com.ningdatech.carapi.common.util.ExcelExportStyle;
import com.ningdatech.carapi.sys.entity.Company;
import com.ningdatech.carapi.sys.entity.CompanyJoin;
import com.ningdatech.carapi.sys.entity.dto.CompanyPageQuery;
import com.ningdatech.carapi.sys.entity.vo.CompanyVO;
import com.ningdatech.carapi.sys.helper.RegionsCacheHelper;
import com.ningdatech.carapi.sys.manage.CompanyManage;
import com.ningdatech.carapi.sys.service.CompanyService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * @Classname RptOtherManage
 * @Description
 * @Date 2022/11/8 17:03
 * @Created by PoffyZhang
 */
@Component
@RequiredArgsConstructor
@Slf4j
public class RptOtherManage {
    private final VehicleTripsManage vehicleTripsManage;

    private final IRptOtherAlarmCleanVehiclesService rptOtherAlarmCleanVehiclesService;
    private final IRptOtherAlarmCleanVehiclesAnalysisService rptOtherAlarmCleanVehiclesAnalysisService;
    private final IRptOtherCrossDomainVehiclesAnalysisService rptOtherCrossDomainVehiclesAnalysisService;
    private final IRptOtherCrossDomainVehiclesService rptOtherCrossDomainVehiclesService;
    private final IRptOtherOnlineVehiclesService rptOtherOnlineVehiclesService;
    private final IRptOtherOnlineVehiclesAnalysisService rptOtherOnlineVehiclesAnalysisService;
    private final IRptOtherSpecialOverspeedService rptOtherSpecialOverspeedService;
    private final IRptOtherSpecialTripsService rptOtherSpecialTripsService;
    private final IRptOtherTerminalInstallService rptOtherTerminalInstallService;

    private final CompanyService companyService;

    public List<RptOtherSpecialOverspeedVO> otherSpecialOverspeed(RptOtherParamDTO param) {
        Page<RptOtherSpecialOverspeedPO> page = param.page();
        rptOtherSpecialOverspeedService.reportPage(page,param);
        if(0L == page.getTotal()){
            return Collections.emptyList();
        }
        return CollUtils.convert(page.getRecords(),w -> {
            RptOtherSpecialOverspeedVO vo = BeanUtil.copyProperties(w, RptOtherSpecialOverspeedVO.class);
            CodeUtil.searchCompanyNameAndRegionName(vo);
            return vo;
        });
    }

    public List<RptOtherSpecialTripsVO> otherSpecialTrips(RptOtherParamDTO param) {
        VehicleTripsParamDTO vehicleTripsParam = new VehicleTripsParamDTO();
        vehicleTripsParam.setRegionId(param.getRegionId());
        vehicleTripsParam.setStartTime(param.getStartTime());
        vehicleTripsParam.setEndTime(param.getEndTime());
        vehicleTripsParam.setVehicleTypes(Arrays.asList(1,2,3,4));
        PageVo<VehicleTripsCityVO> pageList = vehicleTripsManage.lictGroupByCity(vehicleTripsParam);
        if(0L == pageList.getTotal()){
            return Collections.emptyList();
        }
        return CollUtils.convert(pageList.getRecords(),w -> {
            RptOtherSpecialTripsVO vo = BeanUtil.copyProperties(w, RptOtherSpecialTripsVO.class);
            vo.setTrips(w.getVehicleTripsNums());
            return vo;
        });
    }

    public List<RptOtherCompanyTripsVO> otherCompanyTrips(RptOtherParamDTO param) {
        VehicleTripsParamDTO vehicleTripsParam = new VehicleTripsParamDTO();
        vehicleTripsParam.setRegionId(param.getRegionId());
        vehicleTripsParam.setStartTime(param.getStartTime());
        vehicleTripsParam.setEndTime(param.getEndTime());
        PageVo<VehicleTripsCompanyVO> pageList = vehicleTripsManage.lictGroupByCompany(vehicleTripsParam);
        if(0L == pageList.getTotal()){
            return Collections.emptyList();
        }
        return CollUtils.convert(pageList.getRecords(),w -> {
            RptOtherCompanyTripsVO vo = BeanUtil.copyProperties(w, RptOtherCompanyTripsVO.class);
            vo.setTrips(w.getVehicleTripsNums());
            return vo;
        });
    }

    public List<RptOtherOnlineVehiclesVO> otherOnlineVehicles(RptOtherParamDTO param) {
        Page<RptOtherOnlineVehiclesPO> page = param.page();
        companyService.pageVehicleNum(page,param);
        if(0L == page.getTotal()){
            return Collections.emptyList();
        }
        return CollUtils.convert(page.getRecords(),w -> {
             RptOtherOnlineVehiclesVO vo = BeanUtil.copyProperties(w, RptOtherOnlineVehiclesVO.class);
             CodeUtil.searchRegionName(vo);
             return vo;
        });
    }

    public List<RptOtherCrossDomainVehiclesVO> otherCrossDomainVehicles(RptOtherParamDTO param) {
        Page<RptOtherCrossDomainVehiclesPO> page = param.page();
        rptOtherCrossDomainVehiclesService.reportPage(page,param);
        if(0L == page.getTotal()){
            return Collections.emptyList();
        }
        return CollUtils.convert(page.getRecords(),w -> {
            RptOtherCrossDomainVehiclesVO vo = new RptOtherCrossDomainVehiclesVO();
            BeanUtils.copyProperties(w, vo);
            CodeUtil.searchCompanyNameAndRegionName(vo);
            return vo;
        });
    }

    public List<RptOtherAlarmCleanVehiclesVO> otherAlarmCleanVehicles(RptOtherParamDTO param) {
        Page<RptOtherAlarmCleanVehiclesPO> page = param.page();
        rptOtherAlarmCleanVehiclesService.reportPage(page,param);
        if(0L == page.getTotal()){
            return Collections.emptyList();
        }
        return CollUtils.convert(page.getRecords(),w -> {
            RptOtherAlarmCleanVehiclesVO vo = new RptOtherAlarmCleanVehiclesVO();
            BeanUtils.copyProperties(w, vo);
            CodeUtil.searchCompanyNameAndRegionName(vo);
            return vo;
        });
    }

    public List<RptOtherOnlineVehiclesAnalysisVO> otherOnlineAnalysisVehicles(RptOtherParamDTO param) {
        LambdaQueryWrapper<RptOtherOnlineVehiclesAnalysis> wrapper = Wrappers.lambdaQuery(RptOtherOnlineVehiclesAnalysis.class);
        wrapper.like(Objects.nonNull(param.getCompanyName()),RptOtherOnlineVehiclesAnalysis::getCompanyName,param.getCompanyName())
                .eq(Objects.nonNull(param.getRegionId()),RptOtherOnlineVehiclesAnalysis::getRegionId,param.getRegionId())
                .eq(Objects.nonNull(param.getOperatorId()),RptOtherOnlineVehiclesAnalysis::getOperatorId,param.getOperatorId())
                .eq(Objects.nonNull(param.getYearMonth()),RptOtherOnlineVehiclesAnalysis::getYearMonthly,param.getYearMonth())
                .like(Objects.nonNull(param.getEnterpriseType()),RptOtherOnlineVehiclesAnalysis::getEnterpriseType,param.getEnterpriseType())
                .orderBy(Boolean.TRUE,Boolean.FALSE, RptOtherOnlineVehiclesAnalysis::getCreateOn);
        List<RptOtherOnlineVehiclesAnalysis> list = rptOtherOnlineVehiclesAnalysisService.list(wrapper);
        return CollUtils.convert(list,w -> BeanUtil.copyProperties(w,RptOtherOnlineVehiclesAnalysisVO.class));
    }

    public List<RptOtherCrossDomainVehiclesAnalysisVO> otherCrossDomainAnalysisVehicles(RptOtherParamDTO param) {
        LambdaQueryWrapper<RptOtherCrossDomainVehiclesAnalysis> wrapper = Wrappers.lambdaQuery(RptOtherCrossDomainVehiclesAnalysis.class);
        wrapper.like(Objects.nonNull(param.getCompanyName()),RptOtherCrossDomainVehiclesAnalysis::getCompanyName,param.getCompanyName())
                .eq(Objects.nonNull(param.getRegionId()),RptOtherCrossDomainVehiclesAnalysis::getRegionId,param.getRegionId())
                .eq(Objects.nonNull(param.getOperatorId()),RptOtherCrossDomainVehiclesAnalysis::getOperatorId,param.getOperatorId())
                .like(Objects.nonNull(param.getEnterpriseType()),RptOtherCrossDomainVehiclesAnalysis::getEnterpriseType,param.getEnterpriseType())
                .eq(Objects.nonNull(param.getYearMonth()),RptOtherCrossDomainVehiclesAnalysis::getYearMonthly,param.getYearMonth())
                .orderBy(Boolean.TRUE,Boolean.FALSE, RptOtherCrossDomainVehiclesAnalysis::getCreateOn);
        List<RptOtherCrossDomainVehiclesAnalysis> list = rptOtherCrossDomainVehiclesAnalysisService.list(wrapper);
        return CollUtils.convert(list,w -> BeanUtil.copyProperties(w,RptOtherCrossDomainVehiclesAnalysisVO.class));
    }

    public List<RptOtherAlarmCleanVehiclesAnalysisVO> otherAlarmAnalysisVehicles(RptOtherParamDTO param) {
        LambdaQueryWrapper<RptOtherAlarmCleanVehiclesAnalysis> wrapper = Wrappers.lambdaQuery(RptOtherAlarmCleanVehiclesAnalysis.class);
        wrapper.like(Objects.nonNull(param.getCompanyName()),RptOtherAlarmCleanVehiclesAnalysis::getCompanyName,param.getCompanyName())
                .eq(Objects.nonNull(param.getRegionId()),RptOtherAlarmCleanVehiclesAnalysis::getRegionId,param.getRegionId())
                .eq(Objects.nonNull(param.getOperatorId()),RptOtherAlarmCleanVehiclesAnalysis::getOperatorId,param.getOperatorId())
                .eq(Objects.nonNull(param.getYearMonth()),RptOtherAlarmCleanVehiclesAnalysis::getYearMonthly,param.getYearMonth())
                .like(Objects.nonNull(param.getEnterpriseType()),RptOtherAlarmCleanVehiclesAnalysis::getEnterpriseType,param.getEnterpriseType())
                .orderBy(Boolean.TRUE,Boolean.FALSE, RptOtherAlarmCleanVehiclesAnalysis::getCreateOn);
        List<RptOtherAlarmCleanVehiclesAnalysis> list = rptOtherAlarmCleanVehiclesAnalysisService.list(wrapper);
        return CollUtils.convert(list,w -> BeanUtil.copyProperties(w,RptOtherAlarmCleanVehiclesAnalysisVO.class));
    }

    public List<RptOtherTerminalInstallVO> otherTerminalInstall(RptOtherParamDTO param) {
        LambdaQueryWrapper<RptOtherTerminalInstall> wrapper = Wrappers.lambdaQuery(RptOtherTerminalInstall.class);
        wrapper.like(Objects.nonNull(param.getCompanyName()),RptOtherTerminalInstall::getCompanyName,param.getCompanyName())
                .eq(Objects.nonNull(param.getRegionId()),RptOtherTerminalInstall::getRegionId,param.getRegionId())
                .eq(Objects.nonNull(param.getOperatorId()),RptOtherTerminalInstall::getOperatorId,param.getOperatorId())
                .eq(Objects.nonNull(param.getYearMonth()),RptOtherTerminalInstall::getYearMonthly,param.getYearMonth())
                .like(Objects.nonNull(param.getEnterpriseType()),RptOtherTerminalInstall::getEnterpriseType,param.getEnterpriseType())
                .orderBy(Boolean.TRUE,Boolean.FALSE, RptOtherTerminalInstall::getCreateOn);
        List<RptOtherTerminalInstall> list = rptOtherTerminalInstallService.list(wrapper);
        return CollUtils.convert(list,w -> BeanUtil.copyProperties(w,RptOtherTerminalInstallVO.class));
    }

    public void specialVehiclesOverSpeedRecordQueryExport
            (HttpServletResponse response, RptOtherParamDTO param) {
        List<RptOtherSpecialOverspeedVO> collect = otherSpecialOverspeed(param);
        String fileName = "专用车辆超速记录查询";
        ExcelDownUtil.setFileName(fileName, response);
        // 数据导出处理函数
        try {
            EasyExcel.write(response.getOutputStream(), RptOtherSpecialOverspeedVO.class)
                    .autoCloseStream(false)
                    .registerWriteHandler(ExcelExportStyle.formalStyle())
                    .sheet(fileName)
                    .doWrite(collect);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public void specialVehiclesTripsRecordQueryExport
            (HttpServletResponse response, RptOtherParamDTO param) {
        List<RptOtherSpecialTripsVO> collect = otherSpecialTrips(param);
        String fileName = "专用车辆趟次记录查询导出";
        ExcelDownUtil.setFileName(fileName, response);
        // 数据导出处理函数
        try {
            EasyExcel.write(response.getOutputStream(), RptOtherSpecialTripsVO.class)
                    .autoCloseStream(false)
                    .registerWriteHandler(ExcelExportStyle.formalStyle())
                    .sheet(fileName)
                    .doWrite(collect);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public void enterpriseVehiclesTripsRecordQueryExport
            (HttpServletResponse response, RptOtherParamDTO param) {
        List<RptOtherCompanyTripsVO> collect = otherCompanyTrips(param);
        String fileName = "企业车辆趟次记录查询";
        ExcelDownUtil.setFileName(fileName, response);
        // 数据导出处理函数
        try {
            EasyExcel.write(response.getOutputStream(), RptOtherCompanyTripsVO.class)
                    .autoCloseStream(false)
                    .registerWriteHandler(ExcelExportStyle.formalStyle())
                    .sheet(fileName)
                    .doWrite(collect);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public void vehiclesOnlineStatisticsReportExport
            (HttpServletResponse response, RptOtherParamDTO param) {
        List<RptOtherOnlineVehiclesVO> collect = otherOnlineVehicles(param);
        String fileName = "车辆上线情况统计报表";
        ExcelDownUtil.setFileName(fileName, response);
        // 数据导出处理函数
        try {
            EasyExcel.write(response.getOutputStream(), RptOtherOnlineVehiclesVO.class)
                    .autoCloseStream(false)
                    .registerWriteHandler(ExcelExportStyle.formalStyle())
                    .sheet(fileName)
                    .doWrite(collect);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public void vehiclesCrossDomainStatisticsReportExport(HttpServletResponse response, RptOtherParamDTO param) {
        List<RptOtherCrossDomainVehiclesVO> collect = otherCrossDomainVehicles(param);
        String fileName = "车辆跨域情况统计报表";
        ExcelDownUtil.setFileName(fileName, response);
        // 数据导出处理函数
        try {
            EasyExcel.write(response.getOutputStream(), RptOtherCrossDomainVehiclesVO.class)
                    .autoCloseStream(false)
                    .registerWriteHandler(ExcelExportStyle.formalStyle())
                    .sheet(fileName)
                    .doWrite(collect);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public void vehiclesAlarmClearStatisticsReportExport
            (HttpServletResponse response, RptOtherParamDTO param) {
        List<RptOtherAlarmCleanVehiclesVO> collect = otherAlarmCleanVehicles(param);
        String fileName = "车辆报警清理统计报表";
        ExcelDownUtil.setFileName(fileName, response);
        // 数据导出处理函数
        try {
            EasyExcel.write(response.getOutputStream(), RptOtherAlarmCleanVehiclesVO.class)
                    .autoCloseStream(false)
                    .registerWriteHandler(ExcelExportStyle.formalStyle())
                    .sheet(fileName)
                    .doWrite(collect);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public void vehiclesOnlineSituationAnnulusAnalysisReportExport
            (HttpServletResponse response, RptOtherParamDTO param) {
        List<RptOtherOnlineVehiclesAnalysisVO> collect = otherOnlineAnalysisVehicles(param);
        String fileName = "车辆上线情况同比环比分析";
        ExcelDownUtil.setFileName(fileName, response);
        // 数据导出处理函数
        try {
            EasyExcel.write(response.getOutputStream(), RptOtherOnlineVehiclesAnalysisVO.class)
                    .autoCloseStream(false)
                    .registerWriteHandler(ExcelExportStyle.formalStyle())
                    .sheet(fileName)
                    .doWrite(collect);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public void vehiclesAlarmSituationAnnulusAnalysisReportExport
            (HttpServletResponse response, RptOtherParamDTO param) {
        List<RptOtherAlarmCleanVehiclesAnalysisVO> collect = otherAlarmAnalysisVehicles(param);
        String fileName = "车辆报警情况同比环比分析";
        ExcelDownUtil.setFileName(fileName, response);
        // 数据导出处理函数
        try {
            EasyExcel.write(response.getOutputStream(), RptOtherAlarmCleanVehiclesAnalysisVO.class)
                    .autoCloseStream(false)
                    .registerWriteHandler(ExcelExportStyle.formalStyle())
                    .sheet(fileName)
                    .doWrite(collect);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public void vehiclesCrossDomainSituationAnnulusAnalysisReportExport
            (HttpServletResponse response, RptOtherParamDTO param) {
        List<RptOtherCrossDomainVehiclesAnalysisVO> collect = otherCrossDomainAnalysisVehicles(param);
        String fileName = "车辆跨域情况同比环比分析";
        ExcelDownUtil.setFileName(fileName, response);
        // 数据导出处理函数
        try {
            EasyExcel.write(response.getOutputStream(), RptOtherCrossDomainVehiclesAnalysisVO.class)
                    .autoCloseStream(false)
                    .registerWriteHandler(ExcelExportStyle.formalStyle())
                    .sheet(fileName)
                    .doWrite(collect);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public void enterpriseVehiclesCarTerminalInstallationRateReportExport
            (HttpServletResponse response, RptOtherParamDTO param) {
        List<RptOtherTerminalInstallVO> collect = otherTerminalInstall(param);
        String fileName = "企业车辆车载终端安装率统计";
        ExcelDownUtil.setFileName(fileName, response);
        // 数据导出处理函数
        try {
            EasyExcel.write(response.getOutputStream(), RptOtherTerminalInstallVO.class)
                    .autoCloseStream(false)
                    .registerWriteHandler(ExcelExportStyle.formalStyle())
                    .sheet(fileName)
                    .doWrite(collect);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    //public void nineAreasVehiclesOnlineStatisticsReportExport
    //        (HttpServletResponse response, RptOtherParamDTO param) {
    //    List<RptOtherOnlineVehiclesVO> collect = otherOnlineVehicles(param);
    //    String fileName = "9地区车辆上线情况统计";
    //    ExcelDownUtil.setFileName(fileName, response);
    //    // 数据导出处理函数
    //    try {
    //        EasyExcel.write(response.getOutputStream(), RptOtherOnlineVehiclesVO.class)
    //                .autoCloseStream(false)
    //                .registerWriteHandler(ExcelExportStyle.formalStyle())
    //                .sheet(fileName)
    //                .doWrite(collect);
    //    } catch (IOException e) {
    //        throw new RuntimeException(e);
    //    }
    //}
}
