package com.ningdatech.carapi.scheduler.util;

import java.lang.reflect.Field;
import java.time.LocalDateTime;
import java.util.Objects;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ningdatech.carapi.archives.enums.DriverRelationConstant;
import com.ningdatech.carapi.common.constant.VehicleTypeEnum;
import com.ningdatech.carapi.common.contants.DefValConstants;
import com.ningdatech.carapi.driver.constant.ScoreOperateType;
import com.ningdatech.carapi.driver.entity.DriverInfo;
import com.ningdatech.carapi.driver.entity.DriverScoreInfo;
import com.ningdatech.carapi.driver.entity.DriverScoreRecord;
import com.ningdatech.carapi.driver.entity.StarManage;
import com.ningdatech.carapi.driver.helper.DriverBehaviorScoreHelper;
import com.ningdatech.carapi.driver.model.bo.CodingRuleBO;
import com.ningdatech.carapi.driver.service.IDriverInfoService;
import com.ningdatech.carapi.driver.service.IDriverScoreInfoService;
import com.ningdatech.carapi.driver.service.IDriverScoreRecordService;
import com.ningdatech.carapi.scheduler.contants.TaskConstant;
import com.ningdatech.carapi.sys.entity.enumeration.CodingRuleBehaviorTypeEnum;

import lombok.extern.slf4j.Slf4j;

/**
 * @author CMM
 * @since 2022/12/17 17:49
 */
@Component
@Slf4j
public class DriverScoreUtils {

    @Autowired
    private DriverBehaviorScoreHelper driverBehaviorScoreHelper;
    @Autowired
    private IDriverScoreInfoService iDriverScoreInfoService;
    @Autowired
    private IDriverScoreRecordService iDriverScoreRecordService;

    @Autowired
    private IDriverInfoService driverInfoService;

    private  static DriverScoreUtils driverScoreUtils;

    @PostConstruct
    public void init(){
        driverScoreUtils = this;
        driverScoreUtils.driverBehaviorScoreHelper = this.driverBehaviorScoreHelper;
        driverScoreUtils.iDriverScoreInfoService = this.iDriverScoreInfoService;
        driverScoreUtils.iDriverScoreRecordService = this.iDriverScoreRecordService;
        driverScoreUtils.driverInfoService = this.driverInfoService;
    }

    public static  <T> void updateDriverScoreAndRecord(T entity, CodingRuleBehaviorTypeEnum codingRuleBehaviorTypeEnum, VehicleTypeEnum vehicleTypeEnum){
        Class<?> aClass = entity.getClass();
        Long driverId = null;
        try {
            Field driverIdField = aClass.getDeclaredField("driverId");
            driverIdField.setAccessible(Boolean.TRUE);
            driverId = Objects.nonNull(driverIdField.get(entity)) ? (Long)driverIdField.get(entity) : null;
        } catch (Exception e) {
            log.error("成员变量不存在!");
        }

        CodingRuleBO codingRuleBehaviorScore = driverScoreUtils.driverBehaviorScoreHelper
                .getCodingRuleBehaviorScore(codingRuleBehaviorTypeEnum,vehicleTypeEnum);
        //获取对应行为类型的操作分
        Integer operationScore = codingRuleBehaviorScore.getOperationScore();
        //根据驾驶员ID获取驾驶员分数
        DriverScoreInfo driverScoreInfo = driverScoreUtils.iDriverScoreInfoService.getOne(Wrappers.lambdaQuery(DriverScoreInfo.class)
                .eq(DriverScoreInfo::getDriverId,driverId).last(DefValConstants.LIMIT_1));
        DriverInfo driverInfo = driverScoreUtils.driverInfoService.getById(driverId);
        if (Objects.isNull(driverInfo)){
            log.info("当前更新分数驾驶员信息不存在!");
            return;
        }
        if (Objects.isNull(driverScoreInfo)) {
            driverScoreInfo = new DriverScoreInfo();
            driverScoreInfo.setDriverId(driverInfo.getId());
            driverScoreInfo.setUserId(driverInfo.getUserId());
            driverScoreInfo.setCreateOn(LocalDateTime.now());
            driverScoreInfo.setDriverScore(DriverRelationConstant.DRIVER_FULL_SCORE - operationScore);
        } else {
            Integer driverScore = driverScoreInfo.getDriverScore() - operationScore;
            if (driverScore < 0){
                driverScore = 0;
            }
            driverScoreInfo.setDriverScore(driverScore);
        }
        driverScoreInfo.setUpdateOn(LocalDateTime.now());
        driverScoreUtils.iDriverScoreInfoService.saveOrUpdate(driverScoreInfo);

        DriverScoreRecord saveRecord = new DriverScoreRecord();
        saveRecord.setCreateOn(LocalDateTime.now());
        saveRecord.setUpdateOn(LocalDateTime.now());
        saveRecord.setDriverId(driverInfo.getId());
        saveRecord.setOperateReason("驾驶员异常行为扣分");
        saveRecord.setOperateScore(DriverRelationConstant.DRIVER_FULL_SCORE);
        saveRecord.setOperateType(ScoreOperateType.reduce.name());
        saveRecord.setUserId(driverInfo.getUserId());
        driverScoreUtils.iDriverScoreRecordService.save(saveRecord);
    }

    public static void getCurrentStar(StarManage starManage) {
        DriverScoreInfo scoreInfo = driverScoreUtils.iDriverScoreInfoService.getOne(Wrappers.lambdaQuery(DriverScoreInfo.class)
                .eq(DriverScoreInfo::getDriverId, starManage.getDriverId()));
        if (Objects.isNull(scoreInfo)){
            return;
        }
        Integer driverScore = scoreInfo.getDriverScore();
        if (driverScore >= TaskConstant.Data.STAR_NUMBER_RANGE_ZERO && driverScore < TaskConstant.Data.STAR_NUMBER_RANGE_TWENTY){
            starManage.setCurrentScore(driverScore);
            starManage.setCurrentStar(TaskConstant.Star.ONE_STAR);
        } else if (driverScore >= TaskConstant.Data.STAR_NUMBER_RANGE_TWENTY && driverScore < TaskConstant.Data.STAR_NUMBER_RANGE_FORTY) {
            starManage.setCurrentScore(driverScore);
            starManage.setCurrentStar(TaskConstant.Star.TWO_STAR);
        }else if (driverScore >= TaskConstant.Data.STAR_NUMBER_RANGE_FORTY && driverScore < TaskConstant.Data.STAR_NUMBER_RANGE_SIXTY){
            starManage.setCurrentScore(driverScore);
            starManage.setCurrentStar(TaskConstant.Star.THREE_STAR);
        }else if (driverScore >= TaskConstant.Data.STAR_NUMBER_RANGE_SIXTY && driverScore < TaskConstant.Data.STAR_NUMBER_RANGE_EIGHTY){
            starManage.setCurrentScore(driverScore);
            starManage.setCurrentStar(TaskConstant.Star.FOUR_STAR);
        }else if (driverScore >= TaskConstant.Data.STAR_NUMBER_RANGE_EIGHTY){
            starManage.setCurrentScore(driverScore);
            starManage.setCurrentStar(TaskConstant.Star.FIVE_STAR);
        }
    }
}
