package com.ningdatech.carapi.driver.manage;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ningdatech.basic.exception.BizException;
import com.ningdatech.carapi.common.constant.UserRoleTypeEnum;
import com.ningdatech.carapi.common.helper.UserInfoHelper;
import com.ningdatech.carapi.common.util.CodeUtil;
import com.ningdatech.carapi.driver.constant.*;
import com.ningdatech.carapi.driver.entity.Certificate;
import com.ningdatech.carapi.driver.entity.DriverInfo;
import com.ningdatech.carapi.driver.model.po.ReqUploadCertificatePO;
import com.ningdatech.carapi.driver.model.vo.ResCertificateVO;
import com.ningdatech.carapi.driver.service.ICertificateService;
import com.ningdatech.carapi.driver.service.IDriverInfoService;
import com.ningdatech.carapi.sys.helper.CompaniesCacheHelper;
import com.ningdatech.carapi.user.model.vo.UserBasicInfoVO;
import com.ningdatech.carapi.user.security.auth.model.UserInfoDetails;
import com.ningdatech.carapi.user.util.LoginUserUtil;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import lombok.RequiredArgsConstructor;

/**
 * @author liuxinxin
 * @date 2022/10/26 下午4:20
 */
@Component
@RequiredArgsConstructor
public class CertificateManage {

    private final ICertificateService iCertificateService;
    private final IDriverInfoService iDriverInfoService;

    private final CompaniesCacheHelper companiesCacheHelper;
    private final UserInfoHelper userInfoHelper;

    @Transactional(rollbackFor = Exception.class)
    public void uploadCertificate(ReqUploadCertificatePO request) {

        // 按照登录用户，如果是驾驶员登录，只展示该驾驶员信息
        UserBasicInfoVO userFullInfo = userInfoHelper.getUserFullInfo();
        Long roleId = userFullInfo.getRoleId();
        if (UserRoleTypeEnum.DRIVER_ROLE_ID.getId().equals(roleId)){
            throw new BizException("当前登录用户不能上传合格证!");
        }
        // 获取入参
        String certificateNo = request.getCertificateNo();
        Long driverId = request.getDriverId();
        LocalDateTime expiryDate = request.getExpiryDate();
        LocalDateTime issueDate = request.getIssueDate();
        String issuedBy = request.getIssuedBy();
        String examType = request.getExamType();

        // 校验合格证号是否可用
        Certificate oldCertificate = iCertificateService.getOne(Wrappers.lambdaQuery(Certificate.class)
                .eq(Certificate::getCertificateNo, certificateNo));

        if (Objects.nonNull(oldCertificate)) {
            throw new BizException("证书编号重复!");
        }

        List<Certificate> certificateList = iCertificateService.list(Wrappers.lambdaQuery(Certificate.class)
                .eq(Certificate::getDriverId, driverId)
                .gt(Certificate::getExpiryDate, LocalDateTime.now()));
        if (CollectionUtil.isNotEmpty(certificateList)) {
            throw new BizException("该驾驶员证书已上传");
        }

        // 获取驾驶员信息
        DriverInfo driverInfo = iDriverInfoService.getById(driverId);
        UserInfoDetails user = LoginUserUtil.loginUserDetail();
        // 保存合格证信息
        Certificate saveRecord = new Certificate();
        saveRecord.setCertificateNo(certificateNo);
        saveRecord.setDriverId(driverId);
        saveRecord.setDriverName(driverInfo.getDriverName());
        saveRecord.setExpiryDate(expiryDate);
        saveRecord.setIssueDate(issueDate);
        saveRecord.setIssuedBy(issuedBy);
        saveRecord.setCreateOn(LocalDateTime.now());
        saveRecord.setUpdateOn(LocalDateTime.now());
        saveRecord.setCreateBy(user.getUserId());
        saveRecord.setUserId(driverInfo.getUserId());
        saveRecord.setBirth(driverInfo.getBirth());
        saveRecord.setGender(driverInfo.getGender());
        saveRecord.setNativePlace(driverInfo.getNativePlace());
        saveRecord.setHealth(driverInfo.getHealth());
        saveRecord.setPhoneNo(driverInfo.getPhoneNo());
        saveRecord.setAddress(driverInfo.getAddress());
        saveRecord.setDriverLicenseType(driverInfo.getDriverLicenseType());
        saveRecord.setDriverLicenseNo(driverInfo.getDriverLicenseNo());
        saveRecord.setRemark(request.getRemark());
        saveRecord.setRegionId(user.getRegionId());
        saveRecord.setRegionName(user.getRegionName());
        saveRecord.setCompanyId(user.getCompanyId());
        saveRecord.setCompanyName(user.getCompanyName());
        // 如果是换证培训,替换原来过期的取证培训合格证信息
        if (examType.equals(TrainingTypeEnum.replacement_registration_training.name())){
            Certificate certificate = iCertificateService.getOne(Wrappers.lambdaQuery(Certificate.class)
                    .eq(Certificate::getUserId, driverInfo.getUserId()));
            saveRecord.setId(certificate.getId());
        }
        iCertificateService.saveOrUpdate(saveRecord);

        // 取证报名和换证报名上传合格证之后，更新驾驶员状态并将对应的培训报名类型的可参加培训标志更改为可参加
        if (examType.equals(TrainingTypeEnum.forensic_registration_training.name())){
            driverInfo.setDriverRegistrationStatus(DriverRegistrationStatusEnum.available.name());
            driverInfo.setDriverRegistrationFlag(TrainingRegistrationFlagEnum.CAN_TAKE.getCode());
        }else if (examType.equals(TrainingTypeEnum.replacement_registration_training.name())){
            driverInfo.setReplacementRegistrationStatus(DriverReplacementRegistrationStatusEnum.available.name());
            driverInfo.setReplacementRegistrationFlag(TrainingRegistrationFlagEnum.CAN_TAKE.getCode());
        }
        driverInfo.setUpdateOn(LocalDateTime.now());
        // 更新驾驶员为入职
        driverInfo.setDriverStatus(DriverStatusEnum.induction.name());
        iDriverInfoService.updateById(driverInfo);
    }

    public ResCertificateVO getCertificate(Long driverId) {
        DriverInfo driverInfo = iDriverInfoService.getById(driverId);
        if (Objects.isNull(driverInfo)) {
            throw new BizException("驾驶员信息不存在");
        }
        Certificate certificate = iCertificateService.getOne(Wrappers.lambdaQuery(Certificate.class)
                .eq(Certificate::getUserId, driverInfo.getUserId()));

        ResCertificateVO resCertificateVO = new ResCertificateVO();
        resCertificateVO.setIdCard(driverInfo.getIdCard());
        resCertificateVO.setPhoneNo(driverInfo.getPhoneNo());
        resCertificateVO.setAddress(driverInfo.getAddress());
        BeanUtil.copyProperties(certificate, resCertificateVO);
        CodeUtil.searchCompanyName(resCertificateVO);
        return resCertificateVO;
    }

    public ResCertificateVO getCertificate() {
        Long userId = LoginUserUtil.getUserId();
        Certificate certificate = iCertificateService.getOne(Wrappers.lambdaQuery(Certificate.class)
                .eq(Certificate::getUserId, userId));

        ResCertificateVO resCertificateVO = new ResCertificateVO();
        BeanUtil.copyProperties(certificate, resCertificateVO);
        CodeUtil.searchCompanyName(resCertificateVO);
        return resCertificateVO;
    }
}
