package jnpf.personnels.listeners.impl;

import com.alibaba.excel.context.AnalysisContext;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import jnpf.model.personnels.dto.rewardspunishments.FtbPersonnelsRewardsPunishmentQueryDTO;
import jnpf.model.personnels.po.FtbPersonnelsStaffRoster;
import jnpf.model.personnels.vo.rewardspunishments.FtbEmploymentRecordsExcelERRVO;
import jnpf.model.personnels.vo.rewardspunishments.FtbEmploymentRewardExcelVO;
import jnpf.model.personnels.vo.rewardspunishments.FtbPersonnelsRewardsPunishmentQueryVO;
import jnpf.permission.V2UserApi;
import jnpf.permission.vo.v2.user.api.OrganizeAndPositionAndGradeVO;
import jnpf.personnels.listeners.BaseEasyExcelCommonListener;
import jnpf.personnels.mapper.FtbPersonnelsRewardsPunishmentsMapper;
import jnpf.personnels.service.FtbPersonnelsRewardsPunishmentsService;
import jnpf.personnels.service.FtbPersonnelsStaffRosterService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import javax.validation.groups.Default;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Author: peng.hao
 * @create: 2025/1/6
 */
@Service(value = "ftbPersonnelsRewardsService")
@Slf4j
public class FtbPersonnelsRewardsServiceImpl implements BaseEasyExcelCommonListener<FtbEmploymentRewardExcelVO, FtbEmploymentRecordsExcelERRVO> {

    @Autowired
    FtbPersonnelsRewardsPunishmentsService ftbPersonnelsRewardsPunishmentsService;

    @Resource
    Validator validator;

    @Autowired
    private V2UserApi v2UserApi;

    @Resource
    FtbPersonnelsStaffRosterService staffRosterService;

    @Autowired
    FtbPersonnelsRewardsPunishmentsMapper ftbPersonnelsRewardsPunishmentsMapper;

    @Override
    public void dataValidation(AnalysisContext analysisContext,
                               FtbEmploymentRewardExcelVO data,
                               List<FtbEmploymentRewardExcelVO> nomarlData,
                               List<FtbEmploymentRecordsExcelERRVO> errorData) {
        log.error("解析到一条数据,{}", data.toString());
        String string = returnValidateEntity(data);
        if (nomarlData.size() >= 1000){
            FtbEmploymentRecordsExcelERRVO convert = FtbEmploymentRecordsExcelERRVO.convert(data);
            convert.setErrorRemarks("导入数据已经超过限制1000条;");
            errorData.add(convert);
            return;
        }
        // 数据关系校验
        if (string.isEmpty()
                && StringUtils.isNotEmpty(data.getCurrOrgName())
                && StringUtils.isNotEmpty(data.getCurrPositionName())) {
            OrganizeAndPositionAndGradeVO resultCheck = v2UserApi.checkOrganizeNameBoundPositionNameGradeName(data.getCurrOrgName(), data.getCurrPositionName()
                    , null, null);
            if (resultCheck == null) {
                string += "填写组织和岗位不存在绑定关系;";
            } else {
                data.setCurrOrgId(resultCheck.getOrganizeId());
                data.setCurrPositionId(resultCheck.getPositionId());
            }
        }
        FtbPersonnelsRewardsPunishmentQueryDTO queryDTO = new FtbPersonnelsRewardsPunishmentQueryDTO();
        queryDTO.setStatus(0);
        List<FtbPersonnelsRewardsPunishmentQueryVO> results = ftbPersonnelsRewardsPunishmentsMapper.listQuery(queryDTO);
        String punishmentTypeName = data.getPunishmentTypeName();
        if (StringUtils.isNotEmpty(punishmentTypeName)){
            if (results.stream().noneMatch(v -> v.getRegularName().equals(punishmentTypeName))){
                string += "填写的奖惩类型名称不存在或者已经被禁用;";
            }else {
                FtbPersonnelsRewardsPunishmentQueryVO approvalVO = results.stream().filter(
                        v -> v.getRegularName().equals(punishmentTypeName)).findFirst().get();
                data.setPunishmentTypeId(approvalVO.getId());
                data.setIsRecorded(approvalVO.getIsRecorded());

            }
        }
        if ((StringUtils.isNotEmpty(data.getType() ) && !(data.getType().equals("奖励")|| "乐捐".equals(data.getType()))) ){
            string += "填写奖惩类别不存在;";
        }
        FtbPersonnelsStaffRoster serviceOne = staffRosterService.getOne(Wrappers.<FtbPersonnelsStaffRoster>lambdaQuery()
                .eq(FtbPersonnelsStaffRoster::getName, data.getWorkerName())
                .eq(FtbPersonnelsStaffRoster::getSystemWokerId, data.getEmployeeID())
                .last("limit 1")
        );
        if (serviceOne == null) {
            string += "该员工信息在员工花名册不存在;";
        } else {
            data.setUserId(serviceOne.getUserId());
        }
        String day = data.getDay();
        if (StringUtils.isNotEmpty(day)){
            String time = "yyyy-MM-dd";
            SimpleDateFormat format = new SimpleDateFormat(time);
            try {
                Date parse = format.parse(day);
                data.setDayReal(parse);
                if (day.length() != time.length()) {
                    string += "填写的日期格式不正确;";
                } else if (!day.equals(format.format(parse))) {
                    string += "填写的核算日期不存在;";
                }
            } catch (Exception e) {
                string += "填写的日期格式不正确;";
            }
        }
        String amount = data.getAmount();
        if (StringUtils.isNotEmpty(amount)){
            try {
                BigDecimal bigDecimal = BigDecimal.valueOf(Double.parseDouble(amount)).setScale(2, RoundingMode.HALF_UP);
                data.setAmountReal(bigDecimal);
            } catch (Exception e) {
                string += "填写的奖惩金额格式不正确;";
            }
        }
        // 校验用户组织权限适用范围，返回null则为超级管理员
        if (string.isEmpty()) {
            nomarlData.add(data);
        } else {
            FtbEmploymentRecordsExcelERRVO convert = FtbEmploymentRecordsExcelERRVO.convert(data);
            convert.setErrorRemarks(string);
            errorData.add(convert);
        }
    }

    @Override
    public void saveDataToRedis(List<FtbEmploymentRewardExcelVO> nomarlData, List<FtbEmploymentRecordsExcelERRVO> errorData) {
        ftbPersonnelsRewardsPunishmentsService.saveDataToRedis(nomarlData, errorData);
    }

    /**
     * 校验对象-(有返回值)
     *
     * @param object 待校验对象
     * @return 如果返回空 全部校验通过
     */
    public String returnValidateEntity(Object object) {
        Set<ConstraintViolation<Object>> constraintViolations = validator.validate(object, Default.class);
        if (!constraintViolations.isEmpty()) {
            constraintViolations.iterator().next();
            return constraintViolations.stream().map(ConstraintViolation::getMessage).collect(Collectors.joining(";")) + ";";
        }
        return "";
    }
}
