package jnpf.personnels.listeners.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import jnpf.attendance.AttendanceGroupApi;
import jnpf.base.ActionResult;
import jnpf.enums.personnel.PhoneStatusEnum;
import jnpf.model.attendance.vo.AttendanceGroupVo;
import jnpf.model.personnels.po.FtbPersonnelsStaffEmploymentApply;
import jnpf.model.personnels.vo.employment.AddStaffEmploymentApplyExcelERRVO;
import jnpf.model.personnels.vo.employment.AddStaffEmploymentApplyExcelVO;
import jnpf.permission.ContractTypeApi;
import jnpf.permission.PositionApi;
import jnpf.permission.dto.CheckOrgPositionGradesBoundDTO;
import jnpf.personnels.listeners.BaseEasyExcelCommonListener;
import jnpf.personnels.service.FtbPersonnelsBlacklistService;
import jnpf.personnels.service.FtbPersonnelsStaffEmploymentApplyService;
import jnpf.personnels.service.FtbPersonnelsStaffRosterService;
import jnpf.personnels.utils.PersonnelPerUtils;
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.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Title: FtbPersonnelsServiceImpl
 * @Author: peng.hao
 * @create: 2024/2/20 11:09
 */
@Service(value = "ftbPersonnelsService")
@Slf4j
public class FtbPersonnelsServiceImpl implements BaseEasyExcelCommonListener<AddStaffEmploymentApplyExcelVO, AddStaffEmploymentApplyExcelERRVO> {

    @Resource
    private FtbPersonnelsStaffEmploymentApplyService service;

    @Resource
    FtbPersonnelsStaffRosterService staffRosterService;

    @Resource
    Validator validator;

    @Autowired
    private PositionApi positionApi;
    @Autowired
    ContractTypeApi contractTypeApi;

    @Resource
    private FtbPersonnelsBlacklistService ftbPersonnelsBlacklistService;

    @Resource
    AttendanceGroupApi attendanceGroupApi;

    @Autowired
    private PersonnelPerUtils personnelPerUtils;

    @Override
    public void dataValidation(AnalysisContext analysisContext, AddStaffEmploymentApplyExcelVO data,
                               List<AddStaffEmploymentApplyExcelVO> nomarlData,
                               List<AddStaffEmploymentApplyExcelERRVO> errorData) {
        log.error("解析到一条数据,{}", data.toString());
        String string = returnValidateEntity(data);
        // 数据关系校验
        if (string.isEmpty()) {
            CheckOrgPositionGradesBoundDTO checkOrgPositionGradesBoundDTO = new CheckOrgPositionGradesBoundDTO();
            checkOrgPositionGradesBoundDTO.setOrgName(data.getCurrOrgName());
            checkOrgPositionGradesBoundDTO.setPositionName(data.getCurrPositionName());
            checkOrgPositionGradesBoundDTO.setPositionGradesName(data.getCurrRankName());
            CheckOrgPositionGradesBoundDTO resultCheck = positionApi.checkOrgPositionGradesBound(checkOrgPositionGradesBoundDTO);
            if (resultCheck == null) {
                string += "填写所属组织和入职岗位和入职职等不存在绑定关系;";
            } else {
                data.setCurrOrgId(resultCheck.getOrgId());
                data.setCurrPositionId(resultCheck.getPositionId());
                data.setCurrRankId(resultCheck.getPositionGradesId());
            }
        }
        if (StrUtil.isNotBlank(data.getContractTypeName())) {
            String contractTypeName = contractTypeApi.checkContractTypeName(data.getContractTypeName());
            if (StrUtil.isBlank(contractTypeName)) {
                string += "合同类型:" + data.getContractTypeName() + "不在系统内;";
            } else {
                data.setContractTypeName(data.getContractTypeName());
                data.setContractType(contractTypeName);
            }
        }
        // 手机号,离职黑名单校验
        if (ftbPersonnelsBlacklistService.hasItBeenBlacklisted(data.getPhone())) {
            string += "该人员处于黑名单中;";
        }
        //手机号, 员工入职表内手机号检测检测
        FtbPersonnelsStaffEmploymentApply employmentApplyEntity = service.getOne(Wrappers.<FtbPersonnelsStaffEmploymentApply>lambdaQuery()
                .eq(FtbPersonnelsStaffEmploymentApply::getPhone, data.getPhone())
                .last("limit 1")
        );
        if (null != employmentApplyEntity) {
            if (employmentApplyEntity.getIsNeedCheck() == PhoneStatusEnum.BASE_ONBOARD_WAIT.getCode()) {//0、需要审批  1、不需要审批
                string += "手机号已经在入职列表中;";
            } else {
                if (employmentApplyEntity.getCheckStatus() == PhoneStatusEnum.BASE_APPROVAL_WAIT.getCode() && employmentApplyEntity.getStatus() != PhoneStatusEnum.BASE_ONBOARD_WAIT.getCode()) {
                    string += "手机号已经在入职列表中,待到岗;";
                } else if ( employmentApplyEntity.getCheckStatus() == PhoneStatusEnum.BASE_ONBOARD_WAIT.getCode()) {
                    string += "手机号已经在入职审批列表中;";
                } else if (employmentApplyEntity.getCheckStatus() == PhoneStatusEnum.BASE_APPROVAL_REJECT.getCode()) {
                    string += "该手机号已办理入职,但审批流程未通过,请前往待审批列表,进行重新办理;";
                }
            }
        }

        Boolean aBoolean = staffRosterService.checkPhoneExistForRoster(data.getPhone());
        if (aBoolean) {
            string += "手机号已经存在;";
        }
        if (nomarlData.stream().anyMatch(item -> item.getPhone().equals(data.getPhone()))) {
            int i = analysisContext.readRowHolder().getRowIndex() + 2;
            string += "导入手机号在列表第" + i + "行中已经存在;";
        }

        if (StrUtil.isNotBlank(data.getAttendanceGroupName())){
            ActionResult<AttendanceGroupVo> attendanceGroupByName = attendanceGroupApi.getAttendanceGroupByName(data.getCurrOrgName(), data.getAttendanceGroupName());
            if (attendanceGroupByName  == null || attendanceGroupByName.getData() == null){
                string += "考勤组不存在;";
            }else {
                // 构建id
                String id = attendanceGroupByName.getData().getId();
                data.setAttendanceGroup(id);
            }
        }
        try {
            List<String> results = personnelPerUtils.obtainPersonnelOrganizationIdDataPermissions();
            if (( Objects.nonNull(results) && data.getCurrOrgId() != null ) && !results.contains(data.getCurrOrgId())) {
                string +=("导入组织与当前登录人所选权限组织不匹配;");
            }
        }catch (Exception e){
            e.printStackTrace();
            string +=("导入组织与当前登录人所选权限组织不匹配;");
        }
        // 校验用户组织权限适用范围，返回null则为超级管理员
        if (string.isEmpty()) {
            nomarlData.add(data);
        } else {
            AddStaffEmploymentApplyExcelERRVO convert = AddStaffEmploymentApplyExcelERRVO.convert(data);
            convert.setErrorRemarks(string);
            errorData.add(convert);
        }



    }

    @Override
    public void saveDataToRedis(List<AddStaffEmploymentApplyExcelVO> nomarlData, List<AddStaffEmploymentApplyExcelERRVO> errorData) {
        service.saveInRedis(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 "";
    }
}
