package com.ningdatech.carapi.driver;


import java.io.*;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.password.PasswordEncoder;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.ningdatech.basic.util.StrPool;
import com.ningdatech.carapi.AppTests;
import com.ningdatech.carapi.archives.enums.AuditStateEnum;
import com.ningdatech.carapi.car.vehicle.model.NdVehicleBaseInfo;
import com.ningdatech.carapi.car.vehicle.service.IVehicleBaseInfoService;
import com.ningdatech.carapi.common.constant.*;
import com.ningdatech.carapi.driver.constant.DriverRegistrationStatusEnum;
import com.ningdatech.carapi.driver.constant.DriverStatusEnum;
import com.ningdatech.carapi.driver.constant.TrainingRegistrationFlagEnum;
import com.ningdatech.carapi.driver.constant.UserCanLoginEnum;
import com.ningdatech.carapi.driver.entity.Certificate;
import com.ningdatech.carapi.driver.entity.DriverInfo;
import com.ningdatech.carapi.driver.entity.DriverScoreInfo;
import com.ningdatech.carapi.driver.service.ICertificateService;
import com.ningdatech.carapi.driver.service.IDriverInfoService;
import com.ningdatech.carapi.driver.service.IDriverScoreInfoService;
import com.ningdatech.carapi.sys.contants.UserLoginConstant;
import com.ningdatech.carapi.sys.entity.Company;
import com.ningdatech.carapi.sys.entity.Region;
import com.ningdatech.carapi.sys.entity.UserRole;
import com.ningdatech.carapi.sys.entity.dto.OperatorQueryDTO;
import com.ningdatech.carapi.sys.helper.OperatorsCacheHelper;
import com.ningdatech.carapi.sys.helper.RegionsCacheHelper;
import com.ningdatech.carapi.sys.service.CompanyService;
import com.ningdatech.carapi.sys.service.IRegionService;
import com.ningdatech.carapi.sys.service.UserRoleService;
import com.ningdatech.carapi.user.entity.NdUserAuth;
import com.ningdatech.carapi.user.entity.NdUserInfo;
import com.ningdatech.carapi.user.security.auth.constant.AuthTypeEnum;
import com.ningdatech.carapi.user.service.INdUserAuthService;
import com.ningdatech.carapi.user.service.INdUserInfoService;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import lombok.extern.slf4j.Slf4j;

/**
 * @author liuxinxin
 * @date 2022/11/10 下午5:30
 */
@Slf4j
public class DriverDataImportTest extends AppTests {
    @Autowired
    private IDriverInfoService iDriverInfoService;
    @Autowired
    private CompanyService companyService;
    @Autowired
    private IRegionService regionService;
    @Autowired
    private RegionsCacheHelper regionCacheHelper;
    @Autowired
    private INdUserInfoService iNdUserInfoService;
    @Autowired
    private INdUserAuthService iNdUserAuthService;
    @Autowired
    private UserRoleService userRoleService;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private ICertificateService certificateService;
    @Autowired
    private IDriverScoreInfoService iDriverScoreInfoService;
    @Autowired
    private IVehicleBaseInfoService vehicleBaseInfoService;
    @Autowired
    private OperatorsCacheHelper operatorsCacheHelper;

    @Value("${login.public-key}")
    private String publicKey;

    @Value("${login.private-key}")
    private String privateKey;

    @Test
    public void importData() {

//        try {
//            Workbook wb;
//            File file = new File("/Users/liuxinxin/Desktop/driver_data_20221111.xls");
//            InputStream is = Files.newInputStream(file.toPath());
//            wb = Workbook.getWorkbook(is);
//
//            Sheet sheet = wb.getSheet(0);
//            int row_total = sheet.getRows();
//
//            List<DriverInfo> saveRecordList = new ArrayList<>();
//            List<Long> firmIdList = new ArrayList<>();
//            for (int j = 0; j < row_total; j++) {
//                if (j >= 1) {
//                    Cell[] cells = sheet.getRow(j);
//                    String firmId = cells[53].getContents();
//                    if (StringUtils.isNotBlank(firmId)) {
//                        firmIdList.add(Long.parseLong(firmId));
//                    }
//                }
//            }
//            Assert.assertNotNull(firmIdList);
//            firmIdList = firmIdList.stream().distinct().collect(Collectors.toList());
//            List<Company> companyList = companyService.list(new QueryWrapper<Company>()
//                    .in("firm_id", firmIdList));
//            Map<Long, Company> companyMap = companyList.stream().collect(Collectors.toMap(Company::getFirmId, Function.identity()));
//
//
//            for (int j = 0; j < row_total; j++) {
//                if (j >= 1) {
//                    Cell[] cells = sheet.getRow(j);
//                    DriverInfo saveRecord = new DriverInfo();
//                    saveRecord.setDriverName(cells[1].getContents());
////                    saveRecord.setAvatarFile(cells[1].getContents());
//                    saveRecord.setGender("男".equals(cells[3].getContents()) ? 1 : 0);
//                    saveRecord.setIdCard(cells[5].getContents());
//
////                    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
////                    LocalDateTime birth= LocalDateTime.parse(cells[2].getContents(), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
////                    saveRecord.setBirth(birth);
//
//                    saveRecord.setNativePlace(cells[21].getContents());
//
////                    saveRecord.setNativePlaceRegionCode(cells[1].getContents());
//                    saveRecord.setPhoneNo(cells[4].getContents());
//
//                    saveRecord.setHealth("良好");
//                    saveRecord.setAddress(cells[13].getContents());
//
//                    saveRecord.setDriverLicenseNo(cells[6].getContents());
//
//                    String licenseClass = cells[7].getContents();
//
//                    if (StringUtils.isNotBlank(licenseClass) && licenseClass.length() >= 2) {
//                        licenseClass = licenseClass.substring(0, 2);
//                        saveRecord.setDriverLicenseType(licenseClass);
//
//                    }
////                    saveRecord.setCompanyId(cells[1].getContents());
////                    saveRecord.setCompanyName(cells[1].getContents());
//                    saveRecord.setCreateOn(LocalDateTime.now());
//                    saveRecord.setUpdateOn(LocalDateTime.now());
//                    saveRecord.setDriverStatus(DriverStatusEnum.induction.name());
////                    saveRecord.setUserId(cells[1].getContents());
////                    saveRecord.setRegionId(cells[1].getContents());
//
//                    saveRecord.setDriverRegistrationStatus(DriverRegistrationStatusEnum.available.name());
////                    saveRecord.setIllegalAndIllegalInfo(cells[1].getContents());
////                    saveRecord.setInitialLicenseTime(cells[1].getContents());
////                    saveRecord.setQuitTime(cells[1].getContents());
////                    saveRecord.setInductionTime(cells[1].getContents());
//
////                    saveRecord.setReplacementRegistrationStatus(cells[1].getContents());
////                    saveRecord.setContinuingEducationStatus(cells[1].getContents());
//                    System.out.println(saveRecord);
//
////                    iDriverInfoService.save(saveRecord);
//
//                    String firmId = cells[53].getContents();
//                    if (StringUtils.isNotBlank(firmId)) {
//                        Company company = companyMap.get(Long.parseLong(firmId));
//                        if (Objects.nonNull(company)) {
//                            saveRecord.setCompanyName(company.getName());
//                            saveRecord.setCompanyId(company.getId());
//                            saveRecord.setRegionId(company.getRegionId());
//                        }
//                    }
//                    saveRecordList.add(saveRecord);
//                }
//            }
//
//            List<List<DriverInfo>> split = SplitListUtils.split(saveRecordList, 500);
//            for (List<DriverInfo> saveRecordList1 : split) {
//                iDriverInfoService.saveBatch(saveRecordList1);
//            }
//        } catch (IOException e) {
//            // TODO Auto-generated catch block
//            e.printStackTrace();
//        } catch (BiffException e) {
//            e.printStackTrace();
//        }
    }


    @Test
    public void test() throws FileNotFoundException {
        //File f = new File("C:\\Users\\CMM\\Desktop\\水泥车数据初始化\\0729\\宁波驾驶员数据.xlsx");
        //File f = new File("C:\\Users\\CMM\\Desktop\\水泥车数据初始化\\0729\\宁波驾驶员数据-8-2.xlsx");
        //File f = new File("C:\\Users\\CMM\\Desktop\\水泥车数据初始化\\0729\\湖州安吉驾驶员.xlsx");
        //File f = new File("C:\\Users\\CMM\\Desktop\\水泥车数据初始化\\0729\\嘉兴驾驶员\\嘉兴驾驶员数据.xlsx");
        //File f = new File("C:\\Users\\CMM\\Desktop\\水泥车数据初始化\\0729\\丽水驾驶员\\丽水驾驶员数据.xlsx");
        //File f = new File("C:\\Users\\CMM\\Desktop\\水泥车数据初始化\\0729\\温州驾驶员\\温州驾驶员数据.xlsx");
        //File f = new File("D:\\work\\水泥车驾驶员数据\\驾驶员模板.xlsx");
        //File f = new File("D:\\work\\水泥车驾驶员数据\\金华市驾驶员.xlsx");
        //File f = new File("D:\\work\\水泥车驾驶员数据\\浙江丽水嘉城混凝土有限公司上岗证.xlsx");
        //File f = new File("D:\\work\\水泥车驾驶员数据\\台州市驾驶员.xlsx");
        //File f = new File("D:\\work\\水泥车驾驶员数据\\舟山市驾驶员数据-第一批.xlsx");
        //File f = new File("D:\\work\\水泥车驾驶员数据\\绍兴市驾驶员数据-第一批.xlsx");
        //File f = new File("D:\\work\\水泥车驾驶员数据\\温州平阳驾驶员数据-第二批.xlsx");
        //File f = new File("D:\\work\\水泥车驾驶员数据\\湖州南浔区驾驶员数据-第二批.xlsx");
        //File f = new File("D:\\work\\水泥车驾驶员数据\\丽水遂昌驾驶员数据-第二批.xlsx");
        //File f = new File("D:\\work\\水泥车驾驶员数据\\杭州富阳驾驶员数据-第二批.xlsx");
        //File f = new File("D:\\work\\水泥车驾驶员数据\\杭州淳安驾驶员数据-第三批.xlsx");
        //File f = new File("D:\\work\\水泥车驾驶员数据\\丽水莲都驾驶员数据-第三批.xlsx");
        //File f = new File("D:\\work\\水泥车驾驶员数据\\温州苍南驾驶员数据-第三批.xlsx");
        //File f = new File("D:\\work\\水泥车驾驶员数据\\湖州南浔驾驶员数据-第四批.xlsx");
        //---------------------------------------------------------------------------
        //File f = new File("D:\\work\\水泥车驾驶员数据\\湖州吴兴驾驶员数据-第四批.xlsx");
        //File f = new File("D:\\work\\水泥车驾驶员数据\\湖州长合驾驶员数据-第四批.xlsx");
        //File f = new File("D:\\work\\水泥车驾驶员数据\\衢州常山驾驶员数据-第四批.xlsx");
        //File f = new File("D:\\work\\水泥车驾驶员数据\\衢州江山驾驶员数据-第四批.xlsx");
        //File f = new File("D:\\work\\水泥车驾驶员数据\\衢州开化驾驶员数据-第四批.xlsx");
        //File f = new File("D:\\work\\水泥车驾驶员数据\\衢州龙游驾驶员数据-第四批.xlsx");
        //File f = new File("D:\\work\\水泥车驾驶员数据\\衢州衢江驾驶员数据-第四批.xlsx");
        //File f = new File("D:\\work\\水泥车驾驶员数据\\丽水莲都斯通驾驶员数据-第二批.xlsx");
        //File f = new File("D:\\work\\水泥车驾驶员数据\\衢州衢江市本级驾驶员数据-第四批.xlsx");
        //File f = new File("D:\\work\\水泥车驾驶员数据\\衢州柯城驾驶员数据-第四批.xlsx");
        //File f = new File("D:\\work\\水泥车驾驶员数据\\湖州安吉驾驶员数据-第四批.xlsx");
        //File f = new File("D:\\work\\水泥车驾驶员数据\\嘉兴平湖驾驶员数据-第四批.xlsx");
        //---------------------------------------------------------------------------
        //File f = new File("D:\\work\\水泥车驾驶员数据\\湖州德清驾驶员数据-第五批.xlsx");
        //File f = new File("D:\\work\\水泥车驾驶员数据\\湖州德清驾驶员数据-第五批.xlsx");
        //File f = new File("D:\\work\\水泥车驾驶员数据\\嘉兴经开区驾驶员数据-第六批.xlsx");
        //File f = new File("D:\\work\\水泥车驾驶员数据\\嘉兴海盐县驾驶员数据-第六批.xlsx");
        //File f = new File("D:\\work\\水泥车驾驶员数据\\嘉兴秀洲区驾驶员数据-第六批.xlsx");
        //File f = new File("D:\\work\\水泥车驾驶员数据\\丽水市驾驶员数据-第六批.xlsx");
        //File f = new File("D:\\work\\水泥车驾驶员数据\\台州市驾驶员数据-第六批.xlsx");
        //File f = new File("D:\\work\\水泥车驾驶员数据\\温州龙港市驾驶员数据-第六批.xlsx");
        //File f = new File("D:\\work\\水泥车驾驶员数据\\舟山定海区驾驶员数据-第六批.xlsx");
        //File f = new File("D:\\work\\水泥车驾驶员数据\\舟山高新区驾驶员数据-第六批.xlsx");
        //File f = new File("D:\\work\\水泥车驾驶员数据\\绍兴上虞驾驶员数据-第六批.xlsx");
        //---------------------------------------------------------------------------
        //File f = new File("D:\\work\\水泥车驾驶员数据\\台州市驾驶员数据-第一批.xlsx");
        //File f = new File("D:\\work\\水泥车驾驶员数据\\舟山市驾驶员数据-第七批.xlsx");
        //File f = new File("D:\\work\\水泥车驾驶员数据\\丽水松阳驾驶员数据-第七批.xlsx");
        //File f = new File("D:\\work\\水泥车驾驶员数据\\温州市驾驶员-第七批-2022-2023.xlsx");
        //File f = new File("D:\\work\\水泥车驾驶员数据\\温州市驾驶员-第七批-2020-2021.xlsx");
        //File f = new File("D:\\work\\水泥车驾驶员数据\\金华东阳驾驶员数据-第七批.xlsx");
        //---------------------------------------------------------------------------
        //File f = new File("D:\\work\\水泥车驾驶员数据\\杭州钱塘驾驶员数据-第八批.xlsx");
        File f = new File("D:\\work\\水泥车驾驶员数据\\丽水松阳驾驶员数据-第八批.xlsx");
        Workbook wb = readExcel(new FileInputStream(f),f.getName());
        Row row = null;
        List<Long> userList = Lists.newArrayList();
        if(wb != null){
            //获取第一个sheet
            Sheet sheet = wb.getSheetAt(0);
            //获取最大行数
            int rownum = sheet.getPhysicalNumberOfRows();
            //获取第一行
            row = sheet.getRow(0);

            // 根据区县名称获取区域ID
            HashSet<String> countySet = new HashSet<>();
            Map<String, Region> regionMap = regionService.list().stream()
                    .filter(v -> !StrPool.EMPTY.equals(v.getName()) &&
                            !"市本级".equals(v.getName()) &&
                            countySet.add(v.getName()))
                    .collect(Collectors.toMap(Region::getName, v -> v));
            // 根据企业名查询企业信息
            HashSet<String> companySet = new HashSet<>();
            Map<String, Company> companyNameMap = companyService.list().stream()
                    .filter(v -> !StrPool.EMPTY.equals(v.getName()) &&
                            companySet.add(v.getName()))
                    .collect(Collectors.toMap(Company::getName, v -> v));
            for (int i = 1; i<rownum; i++) {
                row = sheet.getRow(i);

                // 驾驶员姓名
                String driverName = Objects.nonNull(row.getCell(0)) ? row.getCell(0).toString() : StringUtils.EMPTY;
                // 身份证号
                String idCard = Objects.nonNull(row.getCell(1)) ? row.getCell(1).toString() : StringUtils.EMPTY;
                // 驾驶证号同身份证号
                String driverLicenseNo = idCard;
                // 出生年月
                Date birth = Objects.nonNull(row.getCell(2)) ? row.getCell(2).getDateCellValue() : null;
                // 性别
                String gender = Objects.nonNull(row.getCell(3)) ? row.getCell(3).toString() : StringUtils.EMPTY;
                // 籍贯
                String nativePlace = Objects.nonNull(row.getCell(4)) ? row.getCell(4).toString() : StringUtils.EMPTY;
                // 籍贯编码
                String nativePlaceRegionCode = Objects.nonNull(row.getCell(5)) ? row.getCell(5).toString() : StringUtils.EMPTY;
                // 健康状况
                String health = Objects.nonNull(row.getCell(6)) ? row.getCell(6).toString() : StringUtils.EMPTY;
                // 手机号码
                Cell cell = row.getCell(7);
                if (cell.getCellType() == CellType.NUMERIC){
                    cell.setCellType(CellType.STRING);
                }
                String stringCellValue = cell.getStringCellValue();
                String phoneNo = Objects.nonNull(stringCellValue) ? stringCellValue : StringUtils.EMPTY;
                // 住址
                String address = Objects.nonNull(row.getCell(8)) ? row.getCell(8).toString() : StringUtils.EMPTY;
                // 驾驶证类型
                String driverLicenseType = Objects.nonNull(row.getCell(9)) ? row.getCell(9).toString() : StringUtils.EMPTY;
                // 拟驾车型
                String motorcycleTypeList = Objects.nonNull(row.getCell(10)) ? row.getCell(10).toString() : StringUtils.EMPTY;
                // 驾驶证初次申领时间
                Date initialLicenseTime = Objects.nonNull(row.getCell(11)) ? row.getCell(11).   getDateCellValue() : null;
                // 违法违规信息
                String illegalAndIllegalInfo = Objects.nonNull(row.getCell(12)) ? row.getCell(12).toString() : StringUtils.EMPTY;
                // 合格证书编号
                Cell certificateNoCell = row.getCell(13);
                if (certificateNoCell.getCellType() == CellType.NUMERIC){
                    certificateNoCell.setCellType(CellType.STRING);
                }
                String certificateNoCellValue = certificateNoCell.getStringCellValue();
                String certificateNo = Objects.nonNull(certificateNoCellValue) ? certificateNoCellValue : StringUtils.EMPTY;
                // 发证单位
                String issuedBy = Objects.nonNull(row.getCell(14)) ? row.getCell(14).toString() : StringUtils.EMPTY;
                // 发证日期
                Date issueDate = Objects.nonNull(row.getCell(15)) ? row.getCell(15).getDateCellValue() : null;
                // 合格证有效期
                Date expiryDate = Objects.nonNull(row.getCell(16)) ? row.getCell(16).getDateCellValue() : null;
                // 区域名称
                String regionName = Objects.nonNull(row.getCell(17)) ? row.getCell(17).toString() : StringUtils.EMPTY;
                // 区县名称 获取区域ID
                String country = regionName.substring(8);
                Region region = regionMap.get(country);
                Long regionId = null;
                if (Objects.nonNull(region)) {
                    regionId = region.getId();
                }
                // 企业名称
                String companyName = Objects.nonNull(row.getCell(18)) ? row.getCell(18).toString() : StringUtils.EMPTY;
                // 获取企业ID
                Company companyInfo = companyNameMap.get(companyName);
                Long companyId = null;
                if (Objects.nonNull(companyInfo)){
                    companyId = companyInfo.getId();
                }

                DriverInfo driverInfo = new DriverInfo();
                // 根据身份证号获取驾驶员信息
                DriverInfo driver = iDriverInfoService.getOne(Wrappers.lambdaQuery(DriverInfo.class).eq(DriverInfo::getIdCard, idCard));
                if (Objects.nonNull(driver)){
                    driverInfo.setId(driver.getId());
                }
                // todo 创建系统用户 生成userId
                NdUserInfo driverUser = new NdUserInfo();
                NdUserInfo info = iNdUserInfoService.getOne(Wrappers.lambdaQuery(NdUserInfo.class)
                        .eq(NdUserInfo::getMobile, phoneNo));
                if (Objects.nonNull(info)){
                    log.error("该手机号{}已有对应用户{}",phoneNo, info.getUsername());
                    userList.add(info.getId());
                }else {
                    driverUser.setMobile(phoneNo);
                }
                driverUser.setUsername(driverName);
                driverUser.setCompanyId(companyId);
                driverUser.setNickName(driverName);
                driverUser.setCanLogin(UserCanLoginEnum.CAN_LOGIN.getCode());
                driverUser.setCreateOn(LocalDateTime.now());
                driverUser.setUpdateOn(LocalDateTime.now());
                driverUser.setCreateBy(2L);

                driverInfo.setDriverName(driverName);
                GenderEnum genderEnum = GenderEnum.getByValue(gender);
                driverInfo.setGender(genderEnum.getCode());
                driverInfo.setIdCard(idCard);
                if (Objects.nonNull(birth)) {
                    driverInfo.setBirth(birth.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
                }
                driverInfo.setNativePlace(nativePlace);
                driverInfo.setNativePlaceRegionCode(nativePlaceRegionCode);
                driverInfo.setPhoneNo(phoneNo);
                driverInfo.setHealth(health);
                driverInfo.setAddress(address);
                driverInfo.setDriverLicenseNo(driverLicenseNo);
                driverInfo.setDriverLicenseType(driverLicenseType);
                driverInfo.setCompanyId(companyId);
                driverInfo.setCompanyName(companyName);
                driverInfo.setCreateOn(LocalDateTime.now());
                driverInfo.setUpdateOn(LocalDateTime.now());
                // 如果没有所属企业，标记驾驶员为离职
                if (Objects.isNull(companyId)){
                    driverInfo.setDriverStatus(DriverStatusEnum.quit.name());
                }else {
                    driverInfo.setDriverStatus(DriverStatusEnum.induction.name());
                }
                if (iNdUserInfoService.saveOrUpdate(driverUser)){
                    Long userId = driverUser.getId();
                    driverInfo.setUserId(userId);

                    // 创建账号密码
                    NdUserAuth userAuth = iNdUserAuthService.getOne(Wrappers.lambdaQuery(NdUserAuth.class)
                            .eq(NdUserAuth::getUserId, userId));
                    NdUserAuth ndUserAuth = new NdUserAuth();
                    if (Objects.nonNull(userAuth)) {
                        ndUserAuth.setId(userAuth.getId());
                    }
                    ndUserAuth.setCreateOn(LocalDateTime.now());
                    ndUserAuth.setUpdateOn(LocalDateTime.now());
                    ndUserAuth.setAuthType(AuthTypeEnum.ACCOUNT_PASSWORD.name());
                    ndUserAuth.setIdentifier(phoneNo);
                    // 初始密码设为123456Aa
                    ndUserAuth.setCredential(passwordEncoder.encode(UserLoginConstant.LOGIN_PASSWORD));
                    ndUserAuth.setUserId(userId);
                    iNdUserAuthService.saveOrUpdate(ndUserAuth);

                    //将角色和驾驶员账号关联
                    UserRole userRole = new UserRole();
                    UserRole role = userRoleService.getOne(Wrappers.lambdaQuery(UserRole.class)
                            .eq(UserRole::getUserId, userId));
                    if (Objects.nonNull(role)) {
                        userRole.setId(role.getId());
                    }
                    userRole.setUserId(userId);
                    userRole.setRoleId(UserRoleTypeEnum.DRIVER_ROLE_ID.getId());
                    userRoleService.saveOrUpdate(userRole);
                }
                driverInfo.setRegionId(regionId);
                driverInfo.setIllegalAndIllegalInfo(illegalAndIllegalInfo);
                // 取证报名状态、继续教育报名状态、换证报名状态、取证报名标志、继续教育报名标志、换证报名标志、跳槽审核报名状态
                driverInfo.setDriverRegistrationStatus(DriverRegistrationStatusEnum.available.name());
                driverInfo.setDriverRegistrationFlag(TrainingRegistrationFlagEnum.CAN_TAKE.getCode());
                driverInfo.setContinuingEducationStatus(DriverRegistrationStatusEnum.available.name());
                driverInfo.setContinuingEducationFlag(TrainingRegistrationFlagEnum.CAN_TAKE.getCode());
                driverInfo.setReplacementRegistrationStatus(DriverRegistrationStatusEnum.available.name());
                driverInfo.setReplacementRegistrationFlag(TrainingRegistrationFlagEnum.CAN_TAKE.getCode());
                if (Objects.nonNull(initialLicenseTime)) {
                    driverInfo.setInitialLicenseTime(initialLicenseTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
                }
                driverInfo.setInductionTime(LocalDateTime.now());
                List<String> arrayList = Lists.newArrayList();
                if (motorcycleTypeList.contains(StrPool.DASH)){
                    String[] split = motorcycleTypeList.split(StrPool.DASH);
                    List<String> strings = Arrays.asList(split);
                    String collect = strings.stream().map(s -> {
                        DriverVehicleTypeEnum vehicleTypeEnum = DriverVehicleTypeEnum.getEnum(s);
                        return vehicleTypeEnum.name();
                    }).collect(Collectors.joining(StrPool.COMMA));
                    arrayList.add(collect);
                }else {
                    DriverVehicleTypeEnum vehicleTypeEnum = DriverVehicleTypeEnum.getEnum(motorcycleTypeList);
                    if (Objects.nonNull(vehicleTypeEnum)) {
                        arrayList.add(vehicleTypeEnum.name());
                    }
                }
                driverInfo.setMotorcycleTypeList(JSONObject.toJSONString(arrayList));
                iDriverInfoService.saveOrUpdate(driverInfo);
                System.out.println("准备插入 " + i  + "条:" + JSON.toJSONString(driverInfo));


                //生成合格证信息
                Certificate certificate = new Certificate();

                certificate.setDriverId(driverInfo.getId());
                certificate.setUserId(driverInfo.getUserId());
                certificate.setDriverName(driverInfo.getDriverName());
                certificate.setBirth(driverInfo.getBirth());
                certificate.setGender(driverInfo.getGender());
                certificate.setNativePlace(driverInfo.getNativePlace());
                certificate.setHealth(driverInfo.getHealth());
                certificate.setPhoneNo(driverInfo.getPhoneNo());
                certificate.setAddress(driverInfo.getAddress());
                certificate.setDriverLicenseType(driverInfo.getDriverLicenseType());
                certificate.setDriverLicenseNo(driverInfo.getDriverLicenseNo());
                // 合格证书编号
                certificate.setCertificateNo(certificateNo);
                // 发证单位
                certificate.setIssuedBy(issuedBy);
                if (Objects.nonNull(issueDate)) {
                    certificate.setIssueDate(issueDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
                }
                if (Objects.nonNull(expiryDate)) {
                    certificate.setExpiryDate(expiryDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
                }
                certificate.setRemark(null);
                certificate.setRegionId(driverInfo.getRegionId());
                certificate.setRegionName(regionName);
                certificate.setCompanyId(driverInfo.getCompanyId());
                certificate.setCompanyName(driverInfo.getCompanyName());
                certificate.setCreateOn(LocalDateTime.now());
                certificate.setUpdateOn(LocalDateTime.now());
                certificate.setCreateBy(2L);
                certificateService.save(certificate);
                //生成上车分数信息
                DriverScoreInfo driverScoreInfo = new DriverScoreInfo();
                driverScoreInfo.setCreateOn(LocalDateTime.now());
                driverScoreInfo.setCreateBy(2L);
                driverScoreInfo.setUserId(driverInfo.getUserId());
                driverScoreInfo.setDriverId(driverInfo.getId());
                driverScoreInfo.setDriverScore(60);
                iDriverScoreInfoService.save(driverScoreInfo);
                System.out.println("准备插入 " + i  + "条合格证信息:" + JSON.toJSONString(certificate));
            }
        }
        log.info("重复的手机号对应的用户ID为{}",userList.toString());
        System.out.println(userList);
    }

    @Test
    public void test2() throws FileNotFoundException {
        //File f = new File("C:\\Users\\CMM\\Desktop\\水泥车数据初始化\\0729\\宁波车辆数据.xlsx");
        File f = new File("D:\\work\\水泥车车辆数据\\丽水经济技术开发区车辆数据.xlsx");
        Workbook wb = readExcel(new FileInputStream(f),f.getName());
        Row row = null;
        HashSet<String> useComSet = new HashSet<>();
        HashSet<String> comSet = new HashSet<>();
        HashSet<String> carSet = new HashSet<>();
        if(wb != null) {
            //获取第一个sheet
            Sheet sheet = wb.getSheetAt(0);
            //获取最大行数
            int rownum = sheet.getPhysicalNumberOfRows();
            //获取第一行
            row = sheet.getRow(0);

            // 根据区县名称获取区域ID
            HashSet<String> countySet = new HashSet<>();
            Map<String, Region> regionMap = regionService.list().stream()
                    .filter(v -> !StrPool.EMPTY.equals(v.getName()) &&
                            !"市本级".equals(v.getName()) &&
                            countySet.add(v.getName()))
                    .collect(Collectors.toMap(Region::getName, v -> v));
            // 根据企业名查询企业信息
            HashSet<String> companySet = new HashSet<>();
            Map<String, Company> companyNameMap = companyService.list().stream()
                    .filter(v -> !StrPool.EMPTY.equals(v.getName()) &&
                            companySet.add(v.getName()))
                    .collect(Collectors.toMap(Company::getName, v -> v));

            List<NdVehicleBaseInfo> baseInfos = vehicleBaseInfoService.list().stream()
                    .filter(v -> Objects.isNull(v.getCompanyId())).collect(Collectors.toList());

            Map<String, NdVehicleBaseInfo> baseInfoMap = baseInfos.stream()
                    .collect(Collectors.toMap(NdVehicleBaseInfo::getCarPlate, v -> v));

            for (int i = 1; i < rownum; i++) {

                NdVehicleBaseInfo vehicleBaseInfo = new NdVehicleBaseInfo();

                row = sheet.getRow(i);
                // 车牌号
                String carPlate = Objects.nonNull(row.getCell(0)) ? row.getCell(0).toString() : StringUtils.EMPTY;
                // 车辆类型
                String carType = Objects.nonNull(row.getCell(1)) ? row.getCell(1).toString() : StringUtils.EMPTY;
                // 运营商
                String operatorName = Objects.nonNull(row.getCell(2)) ? row.getCell(2).toString() : StringUtils.EMPTY;
                // 使用企业
                String useCompanyName = Objects.nonNull(row.getCell(3)) ? row.getCell(3).toString() : StringUtils.EMPTY;
                // 所属企业
                String companyName = Objects.nonNull(row.getCell(4)) ? row.getCell(4).toString() : StringUtils.EMPTY;
                NdVehicleBaseInfo baseInfo = baseInfoMap.get(carPlate);
                // 车牌号在无所属企业中
                if (Objects.nonNull(baseInfo)){
                    vehicleBaseInfo.setId(baseInfo.getId());
                    vehicleBaseInfo.setVehicleType(baseInfo.getVehicleType());
                    vehicleBaseInfo.setOperatorId(baseInfo.getOperatorId());
                }
                vehicleBaseInfo.setCarPlate(carPlate);
                if (StringUtils.isNotBlank(carType)) {
                    vehicleBaseInfo.setVehicleType(VehicleTypeEnum.getCodeByDesc(carType));
                }
                if (StringUtils.isNotBlank(operatorName)) {
                    OperatorQueryDTO operatorDto = operatorsCacheHelper.getByName(operatorName);
                    vehicleBaseInfo.setOperatorId(operatorDto.getId());
                }
                // 更新车辆数据
                Company company = companyNameMap.get(companyName);
                vehicleBaseInfo.setRegionId(company.getRegionId());
                vehicleBaseInfo.setRegionName(regionCacheHelper.getDisplayName(company.getRegionId()));
                vehicleBaseInfo.setCompanyId(company.getId());
                vehicleBaseInfo.setUseCompanyId(company.getId());
                vehicleBaseInfo.setUseCompanyName(company.getName());
                vehicleBaseInfo.setAuditState(AuditStateEnum.AUDIT_SUCCESS.getCode());
                vehicleBaseInfo.setVehicleStatus(CarStatusEnum.ENABLE.getCode());
                vehicleBaseInfoService.saveOrUpdate(vehicleBaseInfo);
                System.out.println("准备插入 " + i  + "条:" + JSON.toJSONString(vehicleBaseInfo));
            }
        }
    }

    @Test
    public void test3() throws FileNotFoundException {
        File f = new File("D:\\work\\水泥车车辆数据\\非所属企业车辆.xlsx");
        Workbook wb = readExcel(new FileInputStream(f),f.getName());
        Row row = null;
        if(wb != null) {
            //获取第一个sheet
            Sheet sheet = wb.getSheetAt(0);
            //获取最大行数
            int rownum = sheet.getPhysicalNumberOfRows();
            //获取第一行
            row = sheet.getRow(0);

            // 根据企业名查询企业信息
            HashSet<String> companySet = new HashSet<>();
            Map<String, Company> companyNameMap = companyService.list().stream()
                    .filter(v -> !StrPool.EMPTY.equals(v.getName()) &&
                            companySet.add(v.getName()))
                    .collect(Collectors.toMap(Company::getName, v -> v));

            Map<String, NdVehicleBaseInfo> baseInfoMap = vehicleBaseInfoService.list().stream()
                    .collect(Collectors.toMap(NdVehicleBaseInfo::getCarPlate, v -> v));

            List<String> comList = Lists.newArrayList();
            List<String> carList = Lists.newArrayList();
            for (int i = 1; i < rownum; i++) {

                row = sheet.getRow(i);
                // 所属企业
                String companyName = Objects.nonNull(row.getCell(0)) ? row.getCell(0).toString() : StringUtils.EMPTY;
                // 车牌号
                String carPlate = Objects.nonNull(row.getCell(1)) ? row.getCell(1).toString() : StringUtils.EMPTY;
                Company company = companyNameMap.get(companyName);
                if (Objects.isNull(company)){
                    log.info("企业：{} 不在系统中",companyName);
                    comList.add(companyName);
                }
                NdVehicleBaseInfo baseInfo = baseInfoMap.get(carPlate);
                if (Objects.isNull(baseInfo)){
                    log.info("车牌号：{} 不在系统中",carPlate);
                    carList.add(carPlate);
                    continue;
                }
                // 更新车辆信息
                // 如果车辆所在区域、所属企业和公司及所在区域相同，才更新
                Long regionId = baseInfo.getRegionId();
                Long companyId = baseInfo.getCompanyId();

                Long companyRegionId = company.getRegionId();
                Long id = company.getId();

                if (Objects.nonNull(regionId) && Objects.nonNull(companyId)
                        && regionId.equals(companyRegionId) && companyId.equals(id)) {
                    LambdaUpdateWrapper<NdVehicleBaseInfo> updateWrapper = Wrappers.lambdaUpdate(NdVehicleBaseInfo.class);
                    updateWrapper.set(NdVehicleBaseInfo::getCompanyId, null)
                            .set(NdVehicleBaseInfo::getUseCompanyId, null)
                            .set(NdVehicleBaseInfo::getUseCompanyName, null)
                            .set(NdVehicleBaseInfo::getRegionId, null)
                            .set(NdVehicleBaseInfo::getRegionName, null)
                            .eq(NdVehicleBaseInfo::getCarPlate, baseInfo.getCarPlate());
                    vehicleBaseInfoService.update(updateWrapper);
                    System.out.println("准备更新 " + i + "条:" + JSON.toJSONString(baseInfo));
                }
            }
        }
    }

    @Test
    public void test4() throws FileNotFoundException {
        //File f = new File("D:\\work\\水泥车车辆数据\\丽水中航混凝土有限公司车辆数据.xlsx");
        //File f = new File("D:\\work\\水泥车车辆数据\\丽水莲都区车辆数据-第二批.xlsx");
        //File f = new File("D:\\work\\水泥车车辆数据\\绍兴上虞区车辆数据-第四批.xlsx");
        //File f = new File("D:\\work\\水泥车车辆数据\\舟山定海车辆数据-第五批.xlsx");
        //File f = new File("D:\\work\\水泥车车辆数据\\绍兴柯桥车辆数据-第六批.xlsx");
        File f = new File("D:\\work\\水泥车车辆数据\\丽水松阳车辆数据-第六批.xlsx");
        Workbook wb = readExcel(new FileInputStream(f),f.getName());
        Row row = null;
        HashSet<String> useComSet = new HashSet<>();
        HashSet<String> comSet = new HashSet<>();
        HashSet<String> carSet = new HashSet<>();
        if(wb != null) {
            //获取第一个sheet
            Sheet sheet = wb.getSheetAt(0);
            //获取最大行数
            int rownum = sheet.getPhysicalNumberOfRows();
            //获取第一行
            row = sheet.getRow(0);

            // 根据区县名称获取区域ID
            HashSet<String> countySet = new HashSet<>();
            Map<String, Region> regionMap = regionService.list().stream()
                    .filter(v -> !StrPool.EMPTY.equals(v.getName()) &&
                            !"市本级".equals(v.getName()) &&
                            countySet.add(v.getName()))
                    .collect(Collectors.toMap(Region::getName, v -> v));
            // 根据企业名查询企业信息
            HashSet<String> companySet = new HashSet<>();
            Map<String, Company> companyNameMap = companyService.list().stream()
                    .filter(v -> !StrPool.EMPTY.equals(v.getName()) &&
                            companySet.add(v.getName()))
                    .collect(Collectors.toMap(Company::getName, v -> v));

            // 系统中已经存在的车辆(包括无所属企业的车辆)
            List<NdVehicleBaseInfo> baseInfos = vehicleBaseInfoService.list();

            Map<String, NdVehicleBaseInfo> baseInfoMap = baseInfos.stream()
                    .collect(Collectors.toMap(NdVehicleBaseInfo::getCarPlate, v -> v));

            for (int i = 1; i < rownum; i++) {

                NdVehicleBaseInfo vehicleBaseInfo = new NdVehicleBaseInfo();

                row = sheet.getRow(i);
                // 车牌号
                String carPlate = Objects.nonNull(row.getCell(0)) ? row.getCell(0).toString() : StringUtils.EMPTY;
                // 车牌颜色
                String plateColor = Objects.nonNull(row.getCell(1)) ? row.getCell(1).toString() : StringUtils.EMPTY;
                // 车辆类型
                String vehicleType = Objects.nonNull(row.getCell(2)) ? row.getCell(2).toString() : StringUtils.EMPTY;
                // 总质量
                String standardTonnage = Objects.nonNull(row.getCell(3)) ? row.getCell(3).toString() : StringUtils.EMPTY;
                // 发动机号
                String engineNo = Objects.nonNull(row.getCell(4)) ? row.getCell(4).toString() : StringUtils.EMPTY;
                // 底盘号
                String chassisNo = Objects.nonNull(row.getCell(5)) ? row.getCell(5).toString() : StringUtils.EMPTY;
                // 运营商
                String operatorName = Objects.nonNull(row.getCell(6)) ? row.getCell(6).toString() : StringUtils.EMPTY;
                // 责任驾驶员一
                String responsibleDriverFirst = Objects.nonNull(row.getCell(7)) ? row.getCell(7).toString() : StringUtils.EMPTY;
                // 责任驾驶员一 电话
                String responsibleDriverFirstMobile = Objects.nonNull(row.getCell(8)) ? row.getCell(8).toString() : StringUtils.EMPTY;
                // 排放标准
                String effluentDischargeStandard = Objects.nonNull(row.getCell(9)) ? row.getCell(9).toString() : StringUtils.EMPTY;
                // 使用年限
                String usefulLife = Objects.nonNull(row.getCell(10)) ? row.getCell(10).toString() : StringUtils.EMPTY;
                // 使用企业
                String useCompanyName = Objects.nonNull(row.getCell(11)) ? row.getCell(11).toString() : StringUtils.EMPTY;
                // 所属企业
                String companyName = Objects.nonNull(row.getCell(12)) ? row.getCell(12).toString() : StringUtils.EMPTY;
                // 自编号
                String selfNo = Objects.nonNull(row.getCell(13)) ? row.getCell(13).toString() : StringUtils.EMPTY;
                // 整备质量
                String selfWeight = Objects.nonNull(row.getCell(14)) ? row.getCell(14).toString() : StringUtils.EMPTY;
                NdVehicleBaseInfo baseInfo = baseInfoMap.get(carPlate);
                // 车牌号在无所属企业中
                if (Objects.nonNull(baseInfo)){
                    vehicleBaseInfo.setId(baseInfo.getId());
                }
                vehicleBaseInfo.setCarPlate(carPlate);
                vehicleBaseInfo.setPlateColor(plateColor);
                if (StringUtils.isNotBlank(vehicleType)) {
                    vehicleBaseInfo.setVehicleType(VehicleTypeEnum.getCodeByDesc(vehicleType));
                }
                vehicleBaseInfo.setStandardTonnage(Double.valueOf(standardTonnage));
                vehicleBaseInfo.setEngineNo(engineNo);
                vehicleBaseInfo.setChassisNo(chassisNo);
                OperatorQueryDTO operatorDto = operatorsCacheHelper.getByName(operatorName);
                if (Objects.nonNull(operatorDto)) {
                    vehicleBaseInfo.setOperatorId(operatorDto.getId());
                }
                vehicleBaseInfo.setResponsibleDriverFirst(responsibleDriverFirst);
                vehicleBaseInfo.setResponsibleDriverFirstMobile(responsibleDriverFirstMobile);
                vehicleBaseInfo.setEffluentDischargeStandard(effluentDischargeStandard);
                if (StringUtils.isNotBlank(usefulLife)) {
                    Integer life = (int) Double.parseDouble(usefulLife);
                    vehicleBaseInfo.setUsefulLife(life);
                }
                if (StringUtils.isNotBlank(selfNo)) {
                    vehicleBaseInfo.setSelfNo(selfNo);
                }
                if (StringUtils.isNotBlank(selfWeight)) {
                    vehicleBaseInfo.setSelfWeight(Double.valueOf(selfWeight));
                }
                // 更新车辆数据
                Company company = companyNameMap.get(companyName);
                vehicleBaseInfo.setRegionId(company.getRegionId());
                vehicleBaseInfo.setRegionName(regionCacheHelper.getDisplayName(company.getRegionId()));
                vehicleBaseInfo.setCompanyId(company.getId());
                vehicleBaseInfo.setUseCompanyId(company.getId());
                vehicleBaseInfo.setUseCompanyName(useCompanyName);
                vehicleBaseInfo.setAuditState(AuditStateEnum.AUDIT_SUCCESS.getCode());
                vehicleBaseInfo.setVehicleStatus(CarStatusEnum.ENABLE.getCode());
                vehicleBaseInfoService.saveOrUpdate(vehicleBaseInfo);
                System.out.println("准备插入 " + i  + "条:" + JSON.toJSONString(vehicleBaseInfo));
            }
        }
    }

    @Test
    public void test5(){
        //String username = "dImMTGYAPmUVoRZFly0RTadTvwASVSizaSuH9LFstFJb3t1Izz4HxlNUcE1x7VfwxJDHeWmQOL8Tl/KdWFZXC6lfyfoh1l4jEyInvgHIEBI9cHfxg14IcvCMZ/mEfdcn/BovjSc52vQuBy+EnD65zj6VUiCSJbssleqWjfSKWVc=";
        String pwd = "ThcjwYO/IU1IKdQ5CivzyVreUBLXK79Qhe6DzEhjNWwOf3iGtz8yM0oUG8Ffhy2WqKEqXZ09vSBQm5uSY/U1Yyl2+j1NRIVAg3N5Q6n3nNV5lVFNSoCqhc8vGkRZArkOFJ1Pk5wDn45SHomB2LzKFiDUeckAkIR7RBKkVpfKFPQ=";
        // 将获取到的经过RSA公钥加密后的用户名解密
        RSA rsa = new RSA(privateKey, publicKey);

        // 密码的密文先进行base64解码，之后再进行解密
        //String decryptStr = rsa.decryptStr(username, KeyType.PrivateKey);
        String decryptStr = rsa.decryptStr(pwd, KeyType.PrivateKey);
        //byte[] decrypt = rsa.decrypt(Base64.decode(username), KeyType.PrivateKey);
        //String decryptStr = StrUtil.str(decrypt, CharsetUtil.CHARSET_UTF_8);

        System.out.println("解密后的用户名为：" + decryptStr);
    }

    @Test
    public void test6() throws FileNotFoundException {
        File f = new File("D:\\work\\水泥车安全通报\\事故车牌号.xlsx");
        Workbook wb = readExcel(new FileInputStream(f),f.getName());
        Row row = null;
        if(wb != null) {
            //获取第一个sheet
            Sheet sheet = wb.getSheetAt(0);
            //获取最大行数
            int rownum = sheet.getPhysicalNumberOfRows();
            //获取第一行
            row = sheet.getRow(0);
            List<String> carPlates = Lists.newArrayList();
            for (int i = 1; i < rownum; i++) {
                row = sheet.getRow(i);
                // 车牌号
                String carPlate = Objects.nonNull(row.getCell(0)) ? row.getCell(0).toString() : StringUtils.EMPTY;
                StringBuilder sb = new StringBuilder();
                sb.append("\"" + carPlate + "\"");
                String s = sb.toString();
                carPlates.add(s);
            }

            String collect = carPlates.stream().collect(Collectors.joining(StrPool.COMMA));
            System.out.println(collect);
        }
    }

    @Test
    public void test7(){
        // 获取系统车辆信息
        List<NdVehicleBaseInfo> baseInfos = vehicleBaseInfoService.list(Wrappers.lambdaQuery(NdVehicleBaseInfo.class)
                .eq(NdVehicleBaseInfo::getAuditState, AuditStateEnum.AUDIT_SUCCESS.getCode())
                .select(NdVehicleBaseInfo::getCarPlate, NdVehicleBaseInfo::getVehicleType));
        if (CollUtil.isNotEmpty(baseInfos)) {
            baseInfos.stream().filter(v -> StringUtils.isNotBlank(v.getCarPlate()) && Objects.nonNull(v.getVehicleType()))
                    .collect(Collectors.toMap(NdVehicleBaseInfo::getCarPlate, NdVehicleBaseInfo::getVehicleType));
        }
    }

    //这个下面是单独函数
    public static org.apache.poi.ss.usermodel.Workbook readExcel(InputStream is, String extString){
        Workbook wb = null;
        extString = extString.substring(extString.lastIndexOf("."));
        try {
            if(".xls".equals(extString)){
                return wb = new HSSFWorkbook(is);
            }else if(".xlsx".equals(extString)){
                return wb = new XSSFWorkbook(is);
            }else {
                return wb = null;
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return wb;
    }

    //public fileout void main(String[] args) {
    //    String a = "2023-02-06";
    //    LocalDateTime birthTime = LocalDateTime.parse(a, DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN));
    //    System.out.println(birthTime);
    //}

}
