package com.ningdatech.carapi.driver.manage;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ningdatech.basic.exception.BizException;
import com.ningdatech.basic.model.PageVo;
import com.ningdatech.carapi.driver.constant.ScoreOperateType;
import com.ningdatech.carapi.driver.constant.TrainingStatusEnum;
import com.ningdatech.carapi.driver.constant.TrainingTypeEnum;
import com.ningdatech.carapi.driver.entity.*;
import com.ningdatech.carapi.driver.helper.DriverBehaviorScoreHelper;
import com.ningdatech.carapi.driver.model.bo.CodingRuleBO;
import com.ningdatech.carapi.driver.model.po.ReqScoreBonusPO;
import com.ningdatech.carapi.driver.model.po.ReqScoreListPO;
import com.ningdatech.carapi.driver.model.vo.ResDriverScoreRecordListVO;
import com.ningdatech.carapi.driver.service.*;
import com.ningdatech.carapi.sys.entity.enumeration.CodingRuleBehaviorTypeEnum;
import com.ningdatech.carapi.user.util.LoginUserUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.constraints.NotBlank;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author liuxinxin
 * @date 2022/11/3 下午4:56
 */
@Component
@RequiredArgsConstructor
public class DriverScoreRecordManage {

    private final IDriverScoreRecordService iDriverScoreRecordService;
    private final IDriverScoreInfoService iDriverScoreInfoService;
    private final ITrainingBonusRecordService iTrainingBonusRecordService;
    private final IDriverInfoService iDriverInfoService;
    private final ITrainingOrganizationTrainerService iTrainingOrganizationTrainerService;
    private final ITrainingOrganizationService iTrainingOrganizationService;
    private final DriverBehaviorScoreHelper driverBehaviorScoreHelper;

    public List<ResDriverScoreRecordListVO> list() {
        Long userId = LoginUserUtil.getUserId();
        List<DriverScoreRecord> driverScoreRecordList = iDriverScoreRecordService.list(Wrappers
                .lambdaQuery(DriverScoreRecord.class).eq(DriverScoreRecord::getUserId, userId).orderByDesc(DriverScoreRecord::getCreateOn));
        return driverScoreRecordList.stream().map(r -> {
            ResDriverScoreRecordListVO resVO = new ResDriverScoreRecordListVO();
            BeanUtil.copyProperties(r, resVO);
            return resVO;
        }).collect(Collectors.toList());
    }


    public PageVo<ResDriverScoreRecordListVO> pageList(ReqScoreListPO request) {
        @NotBlank Long driverId = request.getDriverId();
        Integer pageNumber = request.getPageNumber();
        Integer pageSize = request.getPageSize();

        Page<DriverScoreRecord> page = iDriverScoreRecordService.page(new Page<>(pageNumber, pageSize), Wrappers
                .lambdaQuery(DriverScoreRecord.class)
                .eq(DriverScoreRecord::getDriverId, driverId)
                .orderByDesc(DriverScoreRecord::getCreateOn));

        PageVo<ResDriverScoreRecordListVO> pageVo = new PageVo<>();
        long total = page.getTotal();
        if (total > 0) {
            List<ResDriverScoreRecordListVO> resVOList = page.getRecords().stream().map(r -> {
                ResDriverScoreRecordListVO resVO = new ResDriverScoreRecordListVO();
                BeanUtil.copyProperties(r, resVO);
                return resVO;
            }).collect(Collectors.toList());
            pageVo.setRecords(resVOList);
        }
        return pageVo;
    }

    public Integer getScore(Long driverId) {
        DriverScoreInfo driverScoreInfo = iDriverScoreInfoService.getOne(Wrappers.lambdaQuery(DriverScoreInfo.class)
                .eq(DriverScoreInfo::getDriverId, driverId));

        if (Objects.nonNull(driverScoreInfo)) {
            return driverScoreInfo.getDriverScore();
        }
        return 0;
    }

    @Transactional(rollbackFor = Exception.class)
    public void bonus(ReqScoreBonusPO request) {
        Long driverId = request.getDriverId();
        String materialType = request.getMaterialType();
        String behaviorType = request.getBehaviorType();
        Long trainingOrganizationId = request.getTrainingOrganizationId();
        Long trainingMaterialId = request.getTrainingMaterialId();

        DriverInfo driverInfo = iDriverInfoService.getById(driverId);
        if (Objects.isNull(driverInfo)) {
            throw new BizException("该驾驶员信息不存在");
        }

        TrainingOrganization trainingOrganization = iTrainingOrganizationService.getOne(Wrappers.lambdaQuery(TrainingOrganization.class)
                .eq(TrainingOrganization::getId, trainingOrganizationId)
                .eq(TrainingOrganization::getTrainingType, TrainingTypeEnum.transcoding_training.name())
                .eq(TrainingOrganization::getTrainingStatus, TrainingStatusEnum.enable.name())
        );
        if (Objects.isNull(trainingOrganization)) {
            return;
        }
        TrainingBonusRecord one = iTrainingBonusRecordService.getOne(Wrappers.lambdaQuery(TrainingBonusRecord.class)
                .eq(TrainingBonusRecord::getDriverId, driverId)
                .eq(TrainingBonusRecord::getMaterialType, materialType)
                .eq(TrainingBonusRecord::getTrainingMaterialId, trainingMaterialId)
                .eq(TrainingBonusRecord::getTrainingOrganizationId, trainingOrganizationId)
                .eq(TrainingBonusRecord::getBehaviorType, behaviorType));

        if (Objects.isNull(one)) {
            // 获取行为分数
            CodingRuleBO codingRuleBehaviorScore = driverBehaviorScoreHelper.getCodingRuleBehaviorScore(CodingRuleBehaviorTypeEnum.valueOf(behaviorType),null);
            int score = codingRuleBehaviorScore.getOperationScore();

            DriverScoreInfo driverScoreInfo = iDriverScoreInfoService.getOne(Wrappers.lambdaQuery(DriverScoreInfo.class).eq(DriverScoreInfo::getDriverId, driverInfo.getId()));
            if (driverScoreInfo == null) {
                driverScoreInfo = new DriverScoreInfo();
                driverScoreInfo.setDriverId(driverInfo.getId());
                driverScoreInfo.setUserId(driverInfo.getUserId());
                driverScoreInfo.setCreateOn(LocalDateTime.now());
                driverScoreInfo.setDriverScore(score);
            } else {
                driverScoreInfo.setDriverScore(driverScoreInfo.getDriverScore() + score);
            }
            driverScoreInfo.setUpdateOn(LocalDateTime.now());
            iDriverScoreInfoService.saveOrUpdate(driverScoreInfo);

            DriverScoreRecord saveRecord = new DriverScoreRecord();
            saveRecord.setCreateOn(LocalDateTime.now());
            saveRecord.setUpdateOn(LocalDateTime.now());
            saveRecord.setDriverId(driverInfo.getId());
            saveRecord.setOperateReason("参加转码培训并查看了材料");
            saveRecord.setOperateScore(score);
            saveRecord.setOperateType(ScoreOperateType.add.name());
            saveRecord.setUserId(driverInfo.getUserId());
            iDriverScoreRecordService.save(saveRecord);

            TrainingBonusRecord record = new TrainingBonusRecord();
            record.setUserId(driverInfo.getUserId());
            record.setCreateOn(LocalDateTime.now());
            record.setUpdateOn(LocalDateTime.now());
            record.setBehaviorType(behaviorType);
            record.setDriverId(driverId);
            record.setMaterialType(materialType);
            record.setTrainingMaterialId(trainingMaterialId);
            record.setTrainingOrganizationId(trainingOrganizationId);
            record.setCompanyId(driverInfo.getCompanyId());
            record.setRegionId(driverInfo.getRegionId());
            iTrainingBonusRecordService.save(record);
        }
    }
}