package cn.iocoder.yudao.module.custom.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.custom.entity.CarBrand;
import cn.iocoder.yudao.module.custom.entity.CarMain;
import cn.iocoder.yudao.module.custom.entity.CarModel;
import cn.iocoder.yudao.module.custom.entity.CustomerCar;
import cn.iocoder.yudao.module.custom.mapper.CarMainMapper;
import cn.iocoder.yudao.module.custom.mapper.CustomerCarMapper;
import cn.iocoder.yudao.module.custom.service.CarBrandService;
import cn.iocoder.yudao.module.custom.service.CarMainService;
import cn.iocoder.yudao.module.custom.service.CarModelService;
import cn.iocoder.yudao.module.custom.service.CustomerCarService;
import cn.iocoder.yudao.module.custom.vo.BrandAndModelDTO;
import cn.iocoder.yudao.module.custom.vo.CarMainReqVO;
import cn.iocoder.yudao.module.custom.vo.CarMainRespVO;
import cn.iocoder.yudao.module.custom.vo.CustomerMainRespVO;
import cn.iocoder.yudao.module.label.entity.BusiLabel;
import cn.iocoder.yudao.module.label.service.BusiLabelService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.Period;
import java.util.ArrayList;
import java.util.List;

import static cn.iocoder.yudao.common.BaseConstants.*;

/**
 * 车辆信息 Service 实现类
 *
 * @author 后台管理员
 */
@Service
public class CarMainServiceImpl extends ServiceImpl<CarMainMapper, CarMain> implements CarMainService {

    @Autowired
    private CustomerCarMapper customerCarMapper;

    @Autowired
    private CustomerCarService customerCarService;

    @Autowired
    private BusiLabelService busiLabelService;

    @Resource
    private CarBrandService carBrandService;
    @Resource
    private CarModelService carModelService;


    /**
     * 创建车辆信息
     *
     * @param createReqVO 创建信息
     * @return
     */
    @Override
    public CommonResult<String> createCarMain(CarMainReqVO createReqVO) {
        //车牌号license_number，车架号vin，发动机号码engine_number 重复校验
        int checkResult = isDataKeyValueRepeat(createReqVO);
        //如果查重失败
        if (checkResult != 0) {
            switch (checkResult) {
                case 1:
                    return CommonResult.error(4051, "该车牌号已在系统中登记");
                case 2:
                    return CommonResult.error(4052, "该车架号已在系统中登记");
                case 3:
                    return CommonResult.error(4053, "该发动机号码已在系统中登记");

            }
        }
        //车俩品牌型号级联选择器返回值，第一位是品牌，第二位是型号
        List<String> brandAndModel = createReqVO.getBrandAndModel();
        // 插入
        CarMain carMain = BeanUtils.toBean(createReqVO, CarMain.class);
        carMain.setCarBrand(brandAndModel.get(0));
        //判断是否仅填入了品牌
        if (brandAndModel.size() > 1) {
            //填入了型号
            carMain.setCarModel(brandAndModel.get(1));
        } else {
            carMain.setCarModel("");
        }
        //todo 计算下次保养时间，下次保养里程，下次年检时间，保险到期时间
        baseMapper.insert(carMain);
        // 返回
        return CommonResult.success("新增成功");
    }

    /**
     * 更新车辆信息
     *
     * @param updateReqVO 更新信息
     */
    @Override
    public CommonResult<String> updateCarMain(CarMainReqVO updateReqVO) {
        //车牌号license_number，车架号vin，发动机号码engine_number 重复校验
        int checkResult = isDataKeyValueRepeat(updateReqVO);
        //如果查重失败
        if (checkResult != 0) {
            switch (checkResult) {
                case 1:
                    return CommonResult.error(4051, "该车牌号已在系统中登记");
                case 2:
                    return CommonResult.error(4052, "该车架号已在系统中登记");
                case 3:
                    return CommonResult.error(4053, "该发动机号码已在系统中登记");

            }
        }
        //车俩品牌型号级联选择器返回值，第一位是品牌，第二位是型号
        List<String> brandAndModel = updateReqVO.getBrandAndModel();
        // 插入
        CarMain carMain = BeanUtils.toBean(updateReqVO, CarMain.class);
        carMain.setCarBrand(brandAndModel.get(0));
        //判断是否仅填入了品牌
        if (brandAndModel.size() > 1) {
            //填入了型号
            carMain.setCarModel(brandAndModel.get(1));
        } else {
            carMain.setCarModel("");
        }
        //todo 计算下次保养时间，下次保养里程，下次年检时间，保险到期时间
        baseMapper.updateById(carMain);
        return CommonResult.success("修改成功");
    }

    /**
     * 删除车辆信息
     *
     * @param id 编号
     */
    @Override
    public void deleteCarMain(String id) {
        //判断车辆是否发生过业务
        CarMain target = baseMapper.selectById(id);
        if (ObjectUtil.isEmpty(target.getRecentlyHandledBusiness()) && !"".equals(target.getRecentlyHandledBusiness())) {

        }
        // 逻辑删除
        baseMapper.deleteById(id);
    }

    /**
     * 获得车辆信息
     *
     * @param id 编号
     * @return
     */
    @Override
    public CarMainRespVO getCarMain(String id) {
        //数据单查
        CarMainRespVO carMainRespVO = baseMapper.findOne(id);

        List<String> brandAndModel = new ArrayList<>();
        brandAndModel.add(carMainRespVO.getCarBrand());
        brandAndModel.add(carMainRespVO.getCarModel());

        carMainRespVO.setBrandAndModel(brandAndModel);
        //联查客户信息
        List<CustomerMainRespVO> cusList = customerCarMapper.selectCusListByCarId(id);
        carMainRespVO.setCusList(cusList);

        //联查标签信息
        List<BusiLabel> labelList = busiLabelService.listByMainId(id);
        carMainRespVO.setLabelList(labelList);

        return carMainRespVO;
    }

    /**
     * 通过id查询车辆信息
     *
     * @param id 车辆id
     * @return cn.iocoder.yudao.module.custom.vo.CarMainRespVO
     * @author PQZ
     * @date 18:08 2024/10/18
     **/
    @Override
    public CarMainRespVO queryCarById(String id) {
        return baseMapper.findOne(id);
    }

    /**
     * 获得车辆信息分页
     *
     * @param pageReqVO 分页查询
     * @return
     */
    @Override
    public IPage<CarMainRespVO> getCarMainPage(CarMainReqVO pageReqVO) {
        //取分页参数
        Page<CarMainReqVO> page = new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize());
        //分页查询
        return baseMapper.findPage(page, pageReqVO);
    }

    /**
     * 根据userId查询在某租户下的所有车辆列表
     *
     * @param userId 用户ID
     * @return java.util.List<cn.iocoder.yudao.module.custom.entity.CarMain>
     * @author vinjor-M
     * @date 11:56 2024/10/14
     **/
    @Override
    public List<CarMain> selectListByUserId(Long userId) {
        LambdaQueryWrapper<CarMain> queryWrapper = new LambdaQueryWrapper<CarMain>()
                .eq(CarMain::getUserId,userId)
                .groupBy(CarMain::getLicenseNumber)
                .orderByDesc(BaseDO::getCreateTime);
        return this.list(queryWrapper);
    }

    /**
     * 保险/年检/保养提醒列表
     *
     * @param pageReqVO 查询条件
     * @return com.baomidou.mybatisplus.core.metadata.IPage<cn.iocoder.yudao.module.custom.vo.CarMainRespVO>
     * @author PQZ
     * @date 9:08 2024/8/14
     **/
    @Override
    public IPage<CarMainRespVO> remindCarMainPage(CarMainReqVO pageReqVO) {
        Page<CarMainReqVO> page = new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize());
        return baseMapper.remindCarMainPage(page,pageReqVO);
    }

    /**
     * 绑定客户信息
     *
     * @param saveReqVO CustomerMainSaveReqVO实体
     * @return void
     **/
    @Override
    public void bindCustomAndCar(CarMainReqVO saveReqVO) {
        List<CustomerCar> customerCars = new ArrayList<>();
        List<CustomerMainRespVO> cusList = saveReqVO.getCusList();
        List<CarMain> updateCarMainList = new ArrayList<>();
        if (ObjectUtil.isNotEmpty(cusList)) {
            //组装数据
            cusList.forEach(item -> {
                CustomerCar customerCar = new CustomerCar();
                customerCar.setCarId(saveReqVO.getId());
                customerCar.setCusId(item.getId());
                customerCar.setIsOwner(item.getIsOwner());
                customerCars.add(customerCar);
                //组装车辆更新数据
                CarMain updateObj = new CarMain();
                updateObj.setId(saveReqVO.getId());
                updateObj.setUserId(item.getUserId());
                updateCarMainList.add(updateObj);
            });

        }
        customerCarService.bindCustomerCar(saveReqVO.getId(), CUS_SIGN_CAR, customerCars);
        if(!updateCarMainList.isEmpty()){
            this.updateBatchById(updateCarMainList);
        }
    }

    /**
     * 测算车辆下一次保养/检测/保险时间
     *
     * @param reqVO CarMainReqVO
     * @return java.time.LocalDateTime
     * @author PQZ
     * @date 7:45 2024/8/9
     **/
    @Override
    public CarMainRespVO compute(CarMainReqVO reqVO) {
        CarMainRespVO respVO = new CarMainRespVO();
        /*1、测算车辆保险到期时间，车辆保险购买时间不可为空*/
        if (null != reqVO.getInsuranceDate()) {
            respVO.setInsuranceExpiryDate(reqVO.getInsuranceDate().plusYears(1));
        }
        /*2、测算车辆年检临期(车辆类型及车辆注册时间不可为空)*/
        if (null != reqVO.getCarCategory() && null != reqVO.getCarRegisterDate()) {
            respVO.setNextInspectionDate(computeNextInsp(reqVO.getInspectionDate(), reqVO.getCarCategory(), reqVO.getCarRegisterDate()));
        }
        /*3、测算车辆保养里程及下次保养时间*/
        List<String> brandAndModel = reqVO.getBrandAndModel();
        //根据品牌型号获取保养规则
        BrandAndModelDTO rule = getBrandAndModel(brandAndModel);
        //设置保养里程
        if (null != reqVO.getMaintenanceMileage()) {
            respVO.setNextMaintenanceMileage(reqVO.getMaintenanceMileage().add(rule.getRuleMileage()));
        }
        //设置保养时间
        if (null != reqVO.getMaintenanceDate()) {
            respVO.setNextMaintenanceDate(reqVO.getMaintenanceDate().plusMonths(rule.getRuleTime()));
        }
        return respVO;
    }

    /**
     * 根据品牌型号获取保养规则
     *
     * @param brandAndModel List<String>品牌型号集合
     * @return cn.iocoder.yudao.module.custom.vo.BrandAndModelDTO
     * @author PQZ
     * @date 11:41 2024/8/13
     **/
    private BrandAndModelDTO getBrandAndModel(List<String> brandAndModel) {
        BrandAndModelDTO result = new BrandAndModelDTO();
        int ruleTime = 0;
        BigDecimal ruleMileage = new BigDecimal(0);
        if (null != brandAndModel && brandAndModel.size() > 0) {
            //优先以车辆型号绑定的里程及保养时间为准
            if (brandAndModel.size() > 1) {
                //取车辆型号id
                String modelId = brandAndModel.get(1);
                //查询车辆型号
                CarModel carModel = carModelService.getById(modelId);
                if (null != carModel) {
                    ruleTime = carModel.getRuleTime();
                    ruleMileage = carModel.getRuleMileage();
                }
            } else {
                //没有选择型号情况，以车辆品牌绑定规则为准
                String brandId = brandAndModel.get(0);
                //查询车辆品牌
                CarBrand carBrand = carBrandService.getById(brandId);
                if (null != carBrand){
                    ruleTime = carBrand.getRuleTime();
                    ruleMileage = carBrand.getRuleMileage();
                }
            }
        }
        result.setRuleTime(ruleTime);
        result.setRuleMileage(ruleMileage);
        return result;
    }

    /**
     * 计算车辆下次年检时间
     *
     * @param inspectionDate  年检时间
     * @param carCategory     车辆类型
     * @param carRegisterDate 车辆类别
     * @return java.time.LocalDateTime
     * @author PQZ
     * @date 9:51 2024/8/13
     **/
    private LocalDateTime computeNextInsp(LocalDateTime inspectionDate, String carCategory, LocalDateTime carRegisterDate) {
        /*1、基础参数定义*/
        LocalDateTime resultTime = null;
        //车辆是否存在年检时间
        boolean isInspNull = null != inspectionDate;
        //当前时间
        LocalDateTime currentTime = LocalDateTime.now();
        //计算当前时间与车辆注册日期的差值
        Period period = Period.between(carRegisterDate.toLocalDate(), currentTime.toLocalDate());
        //年份差值
        int yearPeriod = period.getYears();

        if (CAR_CATEGORY_PRIVATE.equals(carCategory)) {
            /*2、计算私家车类型车辆下次年检日期*/
            //私家车计算规则，第6、10年需要年检，过后1年1检
            if (yearPeriod < 6) {
                //小于6年情况在第六年车检
                resultTime = carRegisterDate.plusYears(6);
            } else if (yearPeriod < 10) {
                //大于6年小于10年情况
                resultTime = carRegisterDate.plusYears(10);
            } else {
                //大于10情况,一年一检
                if (isInspNull) {
                    resultTime = inspectionDate.plusYears(1);
                }
            }
        } else if (CAR_CATEGORY_TRUCK.equals(carCategory)) {
            /*2、计算货车类型车辆下次年检日期*/
            //货车测算必须传入年检时间
            if (isInspNull) {
                if (yearPeriod <= 10) {
                    //10年内，一年一检
                    resultTime = inspectionDate.plusYears(1);
                } else {
                    //大于10年半年一检
                    resultTime = inspectionDate.plusMonths(6);
                }
            }
        } else {
            /*3、计算非营运车辆下次年检日期*/
            //非营运车辆必须传入年检时间
            if (isInspNull) {
                if (yearPeriod <= 5) {
                    //5年内，一年一检
                    resultTime = inspectionDate.plusYears(1);
                } else {
                    //大于5年半年一检
                    resultTime = inspectionDate.plusMonths(6);
                }
            }
        }
        return resultTime;
    }

    /**
     * 车牌号，车架号，发动机号码 查重
     *
     * @param reqVO
     * @return 0无重复，1车牌号重复，2车架号重复，发动机号码重复
     */
    private int isDataKeyValueRepeat(CarMainReqVO reqVO) {

        //车牌号license_number 查重
        if (ObjectUtil.isNotEmpty(reqVO.getLicenseNumber())) {
            CarMain target = new CarMain();
            target.setLicenseNumber(reqVO.getLicenseNumber());
            List<CarMain> results = baseMapper.isDataKeyValueRepeat(target);
            //判断是否登记过这个车牌号的车辆
            if (results.size() > 0) {
                //无id是新增，有相应登记记录
                if (ObjectUtil.isEmpty(reqVO.getId())) {
                    return 1;
                }
                //有id是修改，如果登记过，比较id查验是否是当前要修改的车辆本身
                for (CarMain item : results) {
                    if (!item.getId().equals(reqVO.getId())) {
                        return 1;
                    }

                }

            }
            //车架号vin 查重
        }
        if (ObjectUtil.isNotEmpty(reqVO.getVin())) {
            CarMain target = new CarMain();
            target.setVin(reqVO.getVin());
            List<CarMain> results = baseMapper.isDataKeyValueRepeat(target);
            //判断是否登记过这个车架号的车辆
            if (results.size() > 0) {
                //无id是新增，有相应登记记录
                if (ObjectUtil.isEmpty(reqVO.getId())) {
                    return 2;
                }
                //有id是修改，如果登记过，比较id查验是否是当前要修改的车辆本身
                for (CarMain item : results) {
                    if (!item.getId().equals(reqVO.getId())) {
                        return 2;
                    }

                }

            }
            //发动机号码engine_number 查重
        }
        if (ObjectUtil.isNotEmpty(reqVO.getEngineNumber())) {
            CarMain target = new CarMain();
            target.setEngineNumber(reqVO.getEngineNumber());
            List<CarMain> results = baseMapper.isDataKeyValueRepeat(target);
            //判断是否登记过这个发动机号的车辆
            if (results.size() > 0) {
                //无id是新增，有相应登记记录
                if (ObjectUtil.isEmpty(reqVO.getId())) {
                    return 3;
                }
                //有id是修改，如果登记过，比较id查验是否是当前要修改的车辆本身
                for (CarMain item : results) {
                    if (!item.getId().equals(reqVO.getId())) {
                        return 3;
                    }

                }

            }

        }
        //返回查验无重复结果
        return 0;

    }


}