package com.gci.boot.modules.vehicles.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.baomidou.mybatisplus.core.assist.ISqlRunner;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gci.boot.common.util.ValidatorUtil;
import com.gci.boot.common.vo.Result;
import com.gci.boot.constant.CommonConstant;
import com.gci.boot.modules.basedata.entity.TbVehicle;
import com.gci.boot.modules.basedata.service.ITbVehicleService;
import com.gci.boot.modules.driver.service.ITbDriverService;
import com.gci.boot.modules.driver.vo.DriverImportVO;
import com.gci.boot.modules.driver.vo.DriverUserVo;
import com.gci.boot.modules.projects.entity.Projects;
import com.gci.boot.modules.projects.mapper.ProjectsMapper;
import com.gci.boot.modules.projects.service.IProjectsService;
import com.gci.boot.modules.system.entity.SysRole;
import com.gci.boot.modules.system.entity.SysUser;
import com.gci.boot.modules.system.service.ISysDictService;
import com.gci.boot.modules.system.service.ISysRoleService;
import com.gci.boot.modules.system.service.ISysUserService;
import com.gci.boot.modules.system.vo.DictModel;
import com.gci.boot.modules.system.vo.LoginUser;
import com.gci.boot.modules.vehicles.entity.*;
import com.gci.boot.modules.vehicles.mapper.TbRepairInfoMapper;
import com.gci.boot.modules.vehicles.service.*;
import com.gci.boot.modules.vehicles.vo.*;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.text.DecimalFormat;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class RepairUpkeepImportServiceImpl implements IRepairUpkeepImportService {
    @Value("${failExcel}")
    private String failExcel;
    @Autowired
    private TbRepairInfoMapper repairInfoMapper;
    @Autowired
    private ISysDictService sysDictService;
    @Autowired
    private IProjectsService projectsService;
    @Autowired
    private ITbRepairInfoService repairInfoService;
    @Autowired
    private ITbVehicleService vehicleService;
    @Autowired
    private ITbUpkeepBillService upkeepBillService;
    @Autowired
    private ITbDriverService driverService;
    @Autowired
    private ISysUserService sysUserService;


    @Override
    public Result<?> repairImport(List<RepairImportVO> list) throws IOException {
        //维修厂
        List<TbRepairAssign> repairShopList = repairInfoMapper.findRepairShop();
        //报修分类
        List<DictModel> repairClassList =  sysDictService.queryDictItemsByCode("repair_class");
        Map<String, String> repairClassMap = repairClassList.stream().collect(Collectors.toMap(DictModel::getText, DictModel::getValue));
        //查用户所有权限车牌
        List<String> plateNumbers = projectsService.queryAllPlateNumberListOfUser();
        //重复项-车牌、时间、维修分类校验重复
        Map<String, List<Integer>> repeatMap = ValidatorUtil.findDuplicates(list, "plateNumber","repairTime","repairClass");
        Set<String> keys = repeatMap.keySet();
        //历史数据
        List<TbRepairInfo> historyList = repairInfoService.list(new LambdaQueryWrapper<TbRepairInfo>().ne(TbRepairInfo::getFlowStatus,9));
        //记录失败的数据
        List<RepairImportVO> failList = new ArrayList<>();
        for(int i = 0; i< list.size(); i++){
            int flag = 0;
            list.get(i).validate();
            if(CollectionUtil.isNotEmpty(list.get(i).getValidationErrors())){
                flag += 1;
            }
            if(!plateNumbers.contains(list.get(i).getPlateNumber())){
                flag += 1;
                list.get(i).putErrorMsg("当前用户没有该车牌号权限或车辆不存在");
                list.get(i).setFormatErrors("1");
            }
            if(StrUtil.isBlank(repairClassMap.getOrDefault(list.get(i).getRepairClass(), null))){
                flag += 1;
                list.get(i).putErrorMsg("报修分类缺少对应字典");
                list.get(i).setFormatErrors("1");
            }else{
                list.get(i).setRepairClassValue(repairClassMap.getOrDefault(list.get(i).getRepairClass(), null));
            }
            if(!checkRepairRepairShop(list.get(i), repairShopList)){
                flag += 1;
                list.get(i).putErrorMsg("维修厂不存在");
                list.get(i).setFormatErrors("1");
            }
            if(StrUtil.isBlank(repairClassMap.getOrDefault(list.get(i).getRepairClassV2(), null))){
                flag += 1;
                list.get(i).putErrorMsg("维修分类缺少对应字典");
                list.get(i).setFormatErrors("1");
            }else{
                list.get(i).setRepairClassV2Value(repairClassMap.getOrDefault(list.get(i).getRepairClassV2(), null));
            }
            if(Objects.nonNull(repeatMap) && repeatMap.containsKey(list.get(i).getPlateNumber() + list.get(i).getRepairTime() + list.get(i).getRepairClass())){
                flag += 1;
                list.get(i).putErrorMsg("存在重复的'车牌号'、'报修时间'、'报修分类'");
                list.get(i).setRepeatErrors("1");
            }
            RepairImportVO finalI = list.get(i);
            if(StrUtil.isNotBlank(finalI.getPlateNumber()) && StrUtil.isNotBlank(finalI.getRepairTime()) && StrUtil.isNotBlank(finalI.getRepairClassValue())){
                //根据车牌号、报修时间、报修分类校验重复--与历史数据
                List<TbRepairInfo> historys = historyList.stream().filter(h -> finalI.getPlateNumber().equals(h.getPlateNumber())
                        && finalI.getRepairClassValue().equals(h.getRepairClass())
                        && finalI.getRepairTime().equals(DateUtil.format(h.getRepairTime(),"yyyy-MM-dd"))).collect(Collectors.toList());
                if(CollectionUtil.isNotEmpty(historys)){
                    flag += 1;
                    list.get(i).putErrorMsg("'车牌号'、'报修时间'、'报修分类'已存在重复历史记录");
                    list.get(i).setRepeatErrors("1");
                }
            }
            if(flag == 0){
                try {
                    //保存数据
                    this.saveRepair(list.get(i));
                }catch (Exception e){
                    e.printStackTrace();
                    list.get(i).putErrorMsg(e.getMessage());
                    list.get(i).setFormatErrors("1");
                    failList.add(list.get(i));
                }
            }else{
                failList.add(list.get(i));
            }
        }
        //处理返回数据
        if (CollectionUtil.isNotEmpty(failList)) {
            JSONObject entries = new JSONObject();
            String fielName = System.currentTimeMillis() + CommonConstant.REPAIR_IMPORT_FAIL_EXCEL_NAME;
            //导出失败数据
            EasyExcel.write(failExcel + fielName, RepairImportVO.class).registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).sheet("导入异常数据").doWrite(failList);
            //格式异常行数
//            List<Integer> indexes = new ArrayList<>();
//            for (int i = 0; i < failList.size(); i++) {
//                if ("1".equals(failList.get(i).getFormatErrors())) {
//                    indexes.add(i+3);
//                }
//            }
//            //数据重复
//            List<Integer> repeatIndexes = new ArrayList<>();
//            for (int i = 0; i < failList.size(); i++) {
//                if ("1".equals(failList.get(i).getRepeatErrors())) {
//                    repeatIndexes.add(i+3);
//                }
//            }
            String errorMsg = "已导入"+ (list.size()-failList.size()) + "条;失败"+ failList.size() +"条;具体失败详情见失败导出信息表";
//            if(CollectionUtil.isNotEmpty(repeatIndexes)){
//                errorMsg += "第"+  repeatIndexes + "行数据重复;";
//            }
//            if(CollectionUtil.isNotEmpty(indexes)){
//                errorMsg += "第"+  indexes + "行数据格式异常";
//            }
            entries.set("msg",errorMsg);
            entries.set("path",fielName);
            return Result.ok(entries);
        }else{
            return Result.ok();
        }
    }

    @Override
    public Result<?> upkeepImport(List<UpkeepImportVO> list) throws IOException {
        //维修厂
        List<TbRepairAssign> repairShopList = repairInfoMapper.findRepairShop();
        //报修分类
        List<DictModel> repairClassList =  sysDictService.queryDictItemsByCode("repair_class");
        Map<String, String> repairClassMap = repairClassList.stream().collect(Collectors.toMap(DictModel::getText, DictModel::getValue));
        //查用户所有权限车牌
        List<String> plateNumbers = projectsService.queryAllPlateNumberListOfUser();
        //查项目车牌上次保养里程等
        List<VehicleInfoVO> vehicleInfoList = repairInfoMapper.findVehicleInfoByProjectId(null);
        //重复项-车牌、实际保养里程校验重复
        Map<String, List<Integer>> repeatMap = ValidatorUtil.findDuplicates(list,"plateNumber","realMileage");
        //记录失败的数据
        List<UpkeepImportVO> failList = new ArrayList<>();
        Set<String> keys = repeatMap.keySet();
        //历史数据
        List<TbUpkeepBill> historyList = upkeepBillService.list(new LambdaQueryWrapper<TbUpkeepBill>().ne(TbUpkeepBill::getFlowStatus,9));
        for(int i = 0; i< list.size(); i++){
            int flag = 0;
            list.get(i).validate();
            if(CollectionUtil.isNotEmpty(list.get(i).getValidationErrors())){
                flag += 1;
            }
            if(!plateNumbers.contains(list.get(i).getPlateNumber())){
                flag += 1;
                list.get(i).putErrorMsg("当前用户没有该车牌号权限或车辆不存在");
                list.get(i).setFormatErrors("1");
            }
            if(StrUtil.isBlank(repairClassMap.getOrDefault(list.get(i).getRepairClass(), null))){
                flag += 1;
                list.get(i).putErrorMsg("保养分类缺少对应字典");
                list.get(i).setFormatErrors("1");
            }else{
                list.get(i).setRepairClassValue(repairClassMap.getOrDefault(list.get(i).getRepairClass(), null));
            }
            if(!checkUpkeepRepairShop(list.get(i), repairShopList)){
                flag += 1;
                list.get(i).putErrorMsg("维修厂不存在");
                list.get(i).setFormatErrors("1");
            }
            if(Objects.nonNull(repeatMap) && repeatMap.containsKey(list.get(i).getPlateNumber() + list.get(i).getRealMileage())){
                flag += 1;
                list.get(i).putErrorMsg("存在重复的'车牌号'、'实际保养里程'");
                list.get(i).setRepeatErrors("1");
            }
            UpkeepImportVO finalI = list.get(i);
            if(StrUtil.isNotBlank(finalI.getPlateNumber()) && StrUtil.isNotBlank(finalI.getRealMileage())){
                //根据车牌号、实际保养里程校验重复--与历史数据
                List<TbUpkeepBill> historys = historyList.stream().filter(h -> finalI.getPlateNumber().equals(h.getPlateNumber())
                        && Objects.nonNull(h.getRealMileage()) && finalI.getRealMileage().equals(h.getRealMileage().toString())).collect(Collectors.toList());
                if(CollectionUtil.isNotEmpty(historys)){
                    flag += 1;
                    list.get(i).putErrorMsg("'车牌号'、'实际保养里程'已存在重复历史记录");
                    list.get(i).setRepeatErrors("1");
                }
            }
            if(StrUtil.isNotEmpty(list.get(i).getStartTime()) && StrUtil.isNotBlank(list.get(i).getEndTime())){
                // 比较开始时间和结束时间
                if (DateUtil.parse(list.get(i).getStartTime(),"yyyy-MM-dd HH:mm:ss")
                        .compareTo(DateUtil.parse(list.get(i).getEndTime(),"yyyy-MM-dd HH:mm:ss")) > 0) {
                    flag += 1;
                    list.get(i).putErrorMsg("'实际保养开始时间'不能大于'实际保养完成时间'");
                    list.get(i).setFormatErrors("1");
                }
            }
            if(flag == 0){
                try {
                    //保存数据
                    this.saveUpkeep(list.get(i), vehicleInfoList);
                }catch (Exception e){
                    e.printStackTrace();
                    list.get(i).setFormatErrors("1");
                    list.get(i).putErrorMsg(e.getMessage());
                    failList.add(list.get(i));
                }
            }else{
                failList.add(list.get(i));
            }
        }
        //处理返回数据
        if (CollectionUtil.isNotEmpty(failList)) {
            JSONObject entries = new JSONObject();
            String fielName =  System.currentTimeMillis() + CommonConstant.UPKEEP_IMPORT_FAIL_EXCEL_NAME;
            //导出失败数据
            EasyExcel.write(failExcel + fielName, UpkeepImportVO.class).registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).sheet("导入异常数据").doWrite(failList);
            //格式异常行数
//            List<Integer> indexes = new ArrayList<>();
//            for (int i = 0; i < failList.size(); i++) {
//                if ("1".equals(failList.get(i).getFormatErrors())) {
//                    indexes.add(i+3);
//                }
//            }
//            //数据重复
//            List<Integer> repeatIndexes = new ArrayList<>();
//            for (int i = 0; i < failList.size(); i++) {
//                if ("1".equals(failList.get(i).getRepeatErrors())) {
//                    repeatIndexes.add(i+3);
//                }
//            }
            String errorMsg = "已导入"+ (list.size()-failList.size()) + "条;失败"+ failList.size() +"条;具体失败详情见失败导出信息表";
//            if(CollectionUtil.isNotEmpty(repeatIndexes)){
//                errorMsg += "第"+  repeatIndexes + "行数据重复;";
//            }
//            if(CollectionUtil.isNotEmpty(indexes)){
//                errorMsg += "第"+  indexes + "行数据格式异常";
//            }
            entries.set("msg",errorMsg);
            entries.set("path",fielName);
            return Result.ok(entries);
        }else{
            return Result.ok();
        }
    }

    /**
     * 维修-校验维修厂是否存在
     */
    private Boolean checkRepairRepairShop(RepairImportVO vo, List<TbRepairAssign> repairShopList) {
        List<String> repairShopNames = repairShopList.stream().map(TbRepairAssign::getRepairShopName).collect(Collectors.toList());
        if(Objects.nonNull(vo) && StrUtil.isNotBlank(vo.getRepairShop())){
            if (repairShopNames.contains(vo.getRepairShop().trim())) {
                TbRepairAssign repairShop = repairShopList.stream().filter(item -> item.getRepairShopName().equals(vo.getRepairShop())).findFirst().get();
                vo.setRepairShopId(repairShop.getRepairShop());
                vo.setContact(repairShop.getContact());
                vo.setContactPhone(repairShop.getContactPhone());
                return true;
            }
        }
        return false;
    }
    /**
     * 维修-录入
     */
    public void saveRepair(RepairImportVO vo){
        TbRepairInfo repairInfo = new TbRepairInfo();
        TbRepairOffer repairOffer = new TbRepairOffer();
        TbRepairAssign repairAssign =new TbRepairAssign();
        //查车辆信息
        LambdaQueryWrapper<TbVehicle> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TbVehicle::getPlateNumber,vo.getPlateNumber());
        TbVehicle vehicle = vehicleService.getOne(queryWrapper);
        //基本信息
        repairInfo.setPlateNumber(vehicle.getPlateNumber());
        repairInfo.setDeliveryTime(vehicle.getDeliveryTime());
        repairInfo.setEngineNumber(vehicle.getEngineNumber());
        repairInfo.setFrameNumber(vehicle.getFrameNumber());
        repairInfo.setVehicleBrand(vehicle.getVehicleBrand());
        repairInfo.setVehicleModel(vehicle.getVehicleModel());
        repairInfo.setVehicleType(vehicle.getVehicleType());
        repairInfo.setVinCode(vehicle.getVinCode());
        repairInfo.setProjectId(vehicle.getProjectId());
        repairInfo.setRepairPeople(vo.getRepairPeople());
        repairInfo.setPhone(vo.getPhone());
        repairInfo.setRepairTime(DateUtil.parse(vo.getRepairTime(),"yyyy-MM-dd"));
        repairInfo.setRepairClass(vo.getRepairClassValue());
        repairInfo.setRepairContent(vo.getRepairContent());
        //指派信息
        repairAssign.setRepairShop(vo.getRepairShopId());
        repairAssign.setContact(vo.getContact());
        repairAssign.setContactPhone(vo.getContactPhone());
        if("是".equals(vo.getIsGuarantee())){
            repairAssign.setIsGuarantee("1");
        }else{
            repairAssign.setIsGuarantee("0");
        }
        //报修信息
        RepairDetailVO repairDetail = new RepairDetailVO();
        repairDetail.setQuantity(Integer.valueOf(vo.getQuantity()));
        repairDetail.setRepairClass(vo.getRepairClassV2Value());
        repairDetail.setRepairContent(vo.getRepairContentV2());
        repairDetail.setUnitPrice(Double.valueOf(vo.getUnitPrice()));
        repairDetail.setWorkHours(Double.valueOf(vo.getWorkHours()));
        repairDetail.setWorkHoursCost(Double.valueOf(vo.getWorkHoursCost()));
        DecimalFormat df = new DecimalFormat("#.##");
        repairDetail.setTotalCost(Double.parseDouble(df.format(repairDetail.getQuantity() * repairDetail.getUnitPrice() + repairDetail.getWorkHours() * repairDetail.getWorkHoursCost())));
        List<RepairDetailVO> repairDetailList = CollectionUtil.newArrayList(repairDetail);
        repairOffer.setContent(vo.getContent());
        repairOffer.setRepairDetailList(repairDetailList);
        repairOffer.setMaterialCost(Double.parseDouble(df.format(repairDetail.getQuantity()*repairDetail.getUnitPrice())));
        repairOffer.setRepairCost(repairDetail.getTotalCost());
        repairOffer.setTotalWorkHours(repairDetail.getWorkHours());
        repairOffer.setTotalWorkHoursCost(Double.parseDouble(df.format(repairDetail.getWorkHours()*repairDetail.getWorkHoursCost())));
        //入库
        RepairDataEntryVO dataEntryVO = new RepairDataEntryVO();
        dataEntryVO.setRepairInfo(repairInfo);
        dataEntryVO.setRepairAssign(repairAssign);
        dataEntryVO.setRepairOffer(repairOffer);
        String result = repairInfoService.addDataEntry(dataEntryVO,null);
        if(StrUtil.isNotBlank(result)){
            throw new RuntimeException(result);
        }
    }

    /**
     * 保养-校验维修厂是否存在
     */
    private Boolean checkUpkeepRepairShop(UpkeepImportVO vo, List<TbRepairAssign> repairShopList) {
        List<String> repairShopNames = repairShopList.stream().map(TbRepairAssign::getRepairShopName).collect(Collectors.toList());
        if(Objects.nonNull(vo) && StrUtil.isNotBlank(vo.getRepairShop())){
            if (repairShopNames.contains(vo.getRepairShop().trim())) {
                TbRepairAssign repairShop = repairShopList.stream().filter(item -> item.getRepairShopName().equals(vo.getRepairShop())).findFirst().get();
                vo.setRepairShopId(repairShop.getRepairShop());
                vo.setContact(repairShop.getContact());
                vo.setContactPhone(repairShop.getContactPhone());
                return true;
            }
        }
        return false;
    }

    /**
     * 保养--数据录入
     */
    public void saveUpkeep(UpkeepImportVO vo, List<VehicleInfoVO> vehicleInfoList){
        TbUpkeepBill upkeepBill = new TbUpkeepBill();
        TbUpkeepOffer upkeepOffer = new TbUpkeepOffer();
        TbUpkeepAssign upkeepAssign = new TbUpkeepAssign();
        //查车辆信息
        VehicleInfoVO vehicle = vehicleInfoList.stream().filter(item -> item.getPlateNumber().equals(vo.getPlateNumber())).findFirst().get();
        //基本信息
        upkeepBill.setProjectId(vehicle.getProjectId());
        upkeepBill.setPlateNumber(vehicle.getPlateNumber());
        upkeepBill.setDeliveryTime(vehicle.getDeliveryTime());
        upkeepBill.setEngineNumber(vehicle.getEngineNumber());
        upkeepBill.setFrameNumber(vehicle.getFrameNumber());
        upkeepBill.setVinCode(vehicle.getVinCode());
        upkeepBill.setVehicleBrand(vehicle.getVehicleBrand());
        upkeepBill.setVehicleModel(vehicle.getVehicleModel());
        upkeepBill.setVehicleType(vehicle.getVehicleType());
        upkeepBill.setLastMileage(Objects.nonNull(vehicle.getLastMileage()) ? vehicle.getLastMileage() : 0);
        upkeepBill.setLastTime(vehicle.getLastTime());
        upkeepBill.setStartTime(DateUtil.parse(vo.getStartTime(),"yyyy-MM-dd HH:mm:ss"));
        upkeepBill.setEndTime(DateUtil.parse(vo.getEndTime(),"yyyy-MM-dd HH:mm:ss"));
        upkeepBill.setRealMileage(Integer.valueOf(vo.getRealMileage()));
        upkeepBill.setContent(vo.getContent());
        upkeepBill.setPredictTime(upkeepBill.getStartTime());
        upkeepBill.setPredictMileage(upkeepBill.getRealMileage());
        //指派信息
        upkeepAssign.setContact(vo.getContact());
        upkeepAssign.setContactPhone(vo.getContactPhone());
        upkeepAssign.setRepairShop(vo.getRepairShopId());
        //保养详情
        RepairDetailVO repairDetail = new RepairDetailVO();
        repairDetail.setQuantity(Integer.valueOf(vo.getQuantity()));
        repairDetail.setRepairClass(vo.getRepairClassValue());
        repairDetail.setRepairContent(vo.getRepairContent());
        repairDetail.setUnitPrice(Double.valueOf(vo.getUnitPrice()));
        repairDetail.setWorkHours(Double.valueOf(vo.getWorkHours()));
        repairDetail.setWorkHoursCost(Double.valueOf(vo.getWorkHoursCost()));
        DecimalFormat df = new DecimalFormat("#.##");
        repairDetail.setTotalCost(Double.parseDouble(df.format(repairDetail.getQuantity()*repairDetail.getUnitPrice() + repairDetail.getWorkHours()*repairDetail.getWorkHoursCost())));
        List<RepairDetailVO> repairDetailList = CollectionUtil.newArrayList(repairDetail);
        upkeepOffer.setRepairDetailList(repairDetailList);
        upkeepOffer.setOfferContent(vo.getOfferContent());
        upkeepOffer.setMaterialCost(Double.parseDouble(df.format(repairDetail.getQuantity()*repairDetail.getUnitPrice())));
        upkeepOffer.setTotalWorkHours(repairDetail.getWorkHours());
        upkeepOffer.setTotalWorkHoursCost(Double.parseDouble(df.format(repairDetail.getWorkHours()*repairDetail.getWorkHoursCost())));
        upkeepOffer.setTotaCost(upkeepOffer.getMaterialCost() + upkeepOffer.getTotalWorkHoursCost());
        //入库
        UpkeepDataEntryVO dataEntryVO = new UpkeepDataEntryVO();
        dataEntryVO.setUpkeepBill(upkeepBill);
        dataEntryVO.setUpkeepAssign(upkeepAssign);
        dataEntryVO.setUpkeepOffer(upkeepOffer);
        String result = upkeepBillService.addDataEntry(dataEntryVO,null);
        if(StrUtil.isNotBlank(result)){
           throw new RuntimeException(result);
        }
    }

    @Override
    public Result<?> driverImport(List<DriverImportVO> list) throws IOException {
        //获取用户项目权限
        List<String> projectIds = projectsService.queryAllProjectListOfUser();
        //获取所有项目
        List<Projects> allProjects = projectsService.listAll();
        //获取用户
        List<SysUser> userList = sysUserService.list();
        List<String> userNames = userList.stream().map(SysUser::getUsername).collect(Collectors.toList());
        //重复项-姓名全程校验重复
        Map<String, List<Integer>> repeatMap = ValidatorUtil.findDuplicates(list,"username");
        Set<String> keys = repeatMap.keySet();
        //记录失败的数据
        List<DriverImportVO> failList = new ArrayList<>();
        for(int i = 0; i< list.size(); i++){
            int flag = 0;
            list.get(i).validate();
            if(CollectionUtil.isNotEmpty(list.get(i).getValidationErrors())){
                flag += 1;
            }
            //校验项目情况
            boolean dealFlag = this.dealProject(allProjects, projectIds, list.get(i));
            if(!dealFlag){
                flag += 1;
                list.get(i).setFormatErrors("1");
            }
            //记录重复
            if(keys.contains(list.get(i).getUsername())){
                flag += 1;
                list.get(i).putErrorMsg("存在重复的'姓名全拼（小写）'");
                list.get(i).setRepeatErrors("1");
            }
            //判断人存在不
            if(userNames.contains(list.get(i).getUsername())){
                flag += 1;
                list.get(i).putErrorMsg("'姓名全拼（小写）'已存在重复历史记录");
                list.get(i).setRepeatErrors("1");
            }
            if(flag == 0){
                try {
                    //保存数据
                    this.saveDriver(list.get(i));
                }catch (Exception e){
                    e.printStackTrace();
                    list.get(i).putErrorMsg(e.getMessage());
                    list.get(i).setFormatErrors("1");
                    failList.add(list.get(i));
                }
            }else{
                failList.add(list.get(i));
            }
        }

        //处理返回数据
        if (CollectionUtil.isNotEmpty(failList)) {
            JSONObject entries = new JSONObject();
            String fielName = System.currentTimeMillis() + CommonConstant.DRIVER_IMPORT_FAIL_EXCEL_NAME;
            //导出失败数据
            EasyExcel.write(failExcel + fielName, DriverImportVO.class).registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).sheet("导入异常数据").doWrite(failList);
            //格式异常行数
//            List<Integer> indexes = new ArrayList<>();
//            for (int i = 0; i < failList.size(); i++) {
//                if ("1".equals(failList.get(i).getFormatErrors())) {
//                    indexes.add(i+2);
//                }
//            }
//            //数据重复
//            List<Integer> repeatIndexes = new ArrayList<>();
//            for (int i = 0; i < failList.size(); i++) {
//                if ("1".equals(failList.get(i).getRepeatErrors())) {
//                    repeatIndexes.add(i+2);
//                }
//            }
            String errorMsg = "已导入"+ (list.size()-failList.size()) + "条;失败"+ failList.size() +"条;具体失败详情见失败导出信息表";
//            if(CollectionUtil.isNotEmpty(repeatIndexes)){
//                errorMsg += "第"+  repeatIndexes + "行数据重复;";
//            }
//            if(CollectionUtil.isNotEmpty(indexes)){
//                errorMsg += "第"+  indexes + "行数据格式异常";
//            }
            entries.set("msg",errorMsg);
            entries.set("path",fielName);
            return Result.ok(entries);
        }else{
            return Result.ok();
        }
    }

    /**
     * 处理项目相关,所属项目是否存在;多个项目是否对应同一客户;是否有项目权限
     */
    public boolean dealProject(List<Projects> allProjects,List<String> projectIds, DriverImportVO vo){
        boolean flag = true;
        //中文逗号隔开
        List<String> projectNames = new ArrayList<>();
        if(StrUtil.isNotBlank(vo.getProjectNames())){
            projectNames = Arrays.asList(vo.getProjectNames().split("，"));
        }
        //不存在的项目
        List<String> notExistProject = new ArrayList<>();
        //没权限的项目
        List<String> notAuthProject = new ArrayList<>();
        //客户id
        List<String> customerIds = new ArrayList<>();
        for(String name : projectNames){
            Projects project = allProjects.stream().filter(p->p.getProjectName().equals(name)).findFirst().orElse(null);
            if(Objects.isNull(project)){
                notExistProject.add(name);
            }else{
                customerIds.add(project.getCustomerId());
                if(!projectIds.contains(project.getId())){
                    notAuthProject.add(name);
                }
                List<String> ids = vo.getProjectIds();
                if(CollectionUtil.isNotEmpty(ids)){
                    ids.add(project.getId());
                }else{
                    ids = CollectionUtil.newArrayList(project.getId());
                }
                vo.setProjectIds(ids);
            }
        }
        if(CollectionUtil.isNotEmpty(notExistProject)){
            vo.putErrorMsg(notExistProject.stream().collect(Collectors.joining(",")) + "项目不存在;");
            flag = false;
        }
        if(CollectionUtil.isNotEmpty(notAuthProject)){
            vo.putErrorMsg(notAuthProject.stream().collect(Collectors.joining(",")) + "无项目权限;");
            flag = false;
        }
        customerIds = customerIds.stream().distinct().collect(Collectors.toList());
        if(CollectionUtil.isNotEmpty(customerIds) && customerIds.size()>1){
            vo.putErrorMsg("存在所属项目非同一客户");
            flag = false;
        }
        if(CollectionUtil.isNotEmpty(customerIds)){
            vo.setCustomerId(customerIds.get(0));
        }
        return flag;
    }

    /**
     * 保存导入用户信息
     */
    public void saveDriver(DriverImportVO vo){
        DriverUserVo item = new DriverUserVo();
        item.setAddress(vo.getAddress());
        if(StrUtil.isNotBlank(vo.getBirthday())){
            item.setBirthday(DateUtil.parse(vo.getBirthday(),"yyyy-MM-dd"));
        }
        item.setCustomerId(vo.getCustomerId());
        item.setEntryStatus("1");
        item.setEntryTime(DateUtil.parse(vo.getEntryTime(),"yyyy-MM-dd"));
        item.setIdCard(vo.getIdCard());
        item.setName(vo.getDriverName());
        item.setPassword("Htzl@123");
        item.setPhone(vo.getPhone());
        item.setRemark(vo.getRemark());
        item.setUsername(vo.getUsername());
        item.setWorkNo(vo.getWorkNo());
        item.setProjectId(String.join(",", vo.getProjectIds()));
        if("男".equals(vo.getSex())){
            item.setSex("1");
        }
        if("女".equals(vo.getSex())){
            item.setSex("0");
        }
        item.setCompany(vo.getCompany());
        item.setEmployeeType(vo.getEmployeeType());
        item.setAge(StrUtil.isNotBlank(vo.getAge()) ? Integer.valueOf(vo.getAge()) : null);
        item.setChildrens(StrUtil.isNotBlank(vo.getChildrens()) ? Integer.valueOf(vo.getChildrens()) : null);
        item.setFileNumber(vo.getFileNumber());
        //是否定位
        if("是".equals(vo.getIsPosition())){
            item.setIsPosition("1");
        }
        if("否".equals(vo.getIsPosition())){
            item.setIsPosition("0");
        }
        //婚姻状态
        List<DictModel> maritalStatusList = sysDictService.queryDictItemsByCode("marital_status");
        Map<String, String> maritalStatusMap = maritalStatusList.stream().collect(Collectors.toMap(DictModel::getText, DictModel::getValue));
        item.setMaritalStatus(maritalStatusMap.getOrDefault(vo.getMaritalStatus(),null));

        driverService.addDriverWithUser(item);
    }

}
