package jnpf.personnels.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import io.seata.spring.annotation.GlobalTransactional;
import jnpf.base.ActionResult;
import jnpf.entity.workflow.PunishmentsApproval;
import jnpf.entity.workflow.PunishmentsApprovalUser;
import jnpf.entity.workflow.RewardApproval;
import jnpf.entity.workflow.RewardApprovalUser;
import jnpf.model.personnels.dto.rewardspunishments.FtbAwardPassedDTO;
import jnpf.model.personnels.dto.rewardspunishments.FtbAwardSubmissionDTO;
import jnpf.model.personnels.dto.rewardspunishments.FtbPenaltySubmissionDTO;
import jnpf.model.personnels.po.FtbPersonnelsRewardsPunishments;
import jnpf.model.personnels.po.FtbPersonnelsStaffEmploymentApply;
import jnpf.model.personnels.po.FtbPersonnelsStaffRoster;
import jnpf.permission.V2UserApi;
import jnpf.permission.vo.v2.user.UserBoundVO;
import jnpf.personnels.mapper.FtbPersonnelsRewardsPunishmentsMapper;
import jnpf.personnels.service.FtbPersonnelsStaffEmploymentApplyService;
import jnpf.personnels.service.FtbPersonnelsStaffRosterService;
import jnpf.personnels.service.FtbRewardsPunishmentsApproveOAService;
import jnpf.workflow.mapper.PunishmentsApprovalMapper;
import jnpf.workflow.mapper.PunishmentsApprovalUserMapper;
import jnpf.workflow.mapper.RewardApprovalMapper;
import jnpf.workflow.mapper.RewardApprovalUserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class FtbRewardsPunishmentsApproveOAServiceImpl implements FtbRewardsPunishmentsApproveOAService {

    @Resource
    private RewardApprovalMapper reputationMapper;
    @Resource
    private RewardApprovalUserMapper reputationUserMapper;
    @Resource
    private PunishmentsApprovalMapper punishmentsApprovalMapper;
    @Resource
    private PunishmentsApprovalUserMapper punishmentsApprovalUserMapper;
    @Resource
    private FtbPersonnelsRewardsPunishmentsMapper ftbPersonnelsRewardsPunishmentsMapper;
    @Autowired
    private V2UserApi v2UserApi;
    @Resource
    private FtbPersonnelsStaffRosterService staffRosterService;
    @Autowired
    private FtbPersonnelsStaffEmploymentApplyService staffEmploymentApplyService;

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void awardSubmission(FtbAwardSubmissionDTO ftbAwardSubmission) {
        validatePunishments(ftbAwardSubmission.getUserDtos());
        RewardApproval rewardApproval = FtbAwardSubmissionDTO.convertRewardApproval(ftbAwardSubmission);
        rewardApproval.setStatus(0);
        // 类别名称
        LambdaQueryWrapper<FtbPersonnelsRewardsPunishments> ftbPersonnelsRewardsPunishmentsLambdaQueryWrapper = Wrappers.lambdaQuery();
        ftbPersonnelsRewardsPunishmentsLambdaQueryWrapper.select(FtbPersonnelsRewardsPunishments::getRegularName, FtbPersonnelsRewardsPunishments::getIsRecorded);
        ftbPersonnelsRewardsPunishmentsLambdaQueryWrapper.eq(FtbPersonnelsRewardsPunishments::getId, ftbAwardSubmission.getType());
        FtbPersonnelsRewardsPunishments ftbPersonnelsRewardsPunishments = ftbPersonnelsRewardsPunishmentsMapper.selectOne(ftbPersonnelsRewardsPunishmentsLambdaQueryWrapper);
        rewardApproval.setTypeName(ftbPersonnelsRewardsPunishments.getRegularName());
        rewardApproval.setIsRecorded(ftbPersonnelsRewardsPunishments.getIsRecorded());
        reputationMapper.insert(rewardApproval);
        String rewardApprovalId = rewardApproval.getId();
        // 奖励人员
        if (CollUtil.isNotEmpty(ftbAwardSubmission.getUserDtos())) {
            ActionResult<List<UserBoundVO>> userPrimaryBoundBatch = v2UserApi.getUserPrimaryBoundBatch(ftbAwardSubmission.getUserDtos(), null);
            if (userPrimaryBoundBatch == null || CollUtil.isEmpty(userPrimaryBoundBatch.getData())) {
                throw new RuntimeException("获取人员信息失败");
            }
            Map<String, UserBoundVO> userIdMap = userPrimaryBoundBatch.getData().stream().collect(Collectors.toMap(UserBoundVO::getId, v -> v));
            ftbAwardSubmission.getUserDtos().forEach(a -> {
                RewardApprovalUser rewardApprovalUser = new RewardApprovalUser();
                rewardApprovalUser.setUserId(a);
                rewardApprovalUser.setApprovalId(rewardApprovalId);
                // 默认组织、岗位、职等
                UserBoundVO partUserInfoVo = userIdMap.get(a);
                if (Objects.nonNull(partUserInfoVo)) {
                    rewardApprovalUser.setOrgName(partUserInfoVo.getOrganizeName());
                    rewardApprovalUser.setPostName(partUserInfoVo.getPositionName());
                    rewardApprovalUser.setGradesName(partUserInfoVo.getGradeName());
                }
                reputationUserMapper.insert(rewardApprovalUser);
            });
        }

    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void awardPassed(FtbAwardPassedDTO ftbAwardPassedDTO) {
        LambdaUpdateWrapper<RewardApproval> updater = Wrappers.lambdaUpdate();
        updater.eq(RewardApproval::getFFlowid, ftbAwardPassedDTO.getTaskId());
        updater.set(RewardApproval::getStatus, ftbAwardPassedDTO.getType());
        reputationMapper.update(new RewardApproval(), updater);
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void penaltySubmission(FtbPenaltySubmissionDTO ftbPenaltySubmissionDTO) {
        validatePunishments(ftbPenaltySubmissionDTO.getUserDtos());
        PunishmentsApproval penaltySubmission = FtbPenaltySubmissionDTO.convertPunishmentsApproval(ftbPenaltySubmissionDTO);
        penaltySubmission.setStatus(0);
        // 类别名称
        LambdaQueryWrapper<FtbPersonnelsRewardsPunishments> ftbPersonnelsRewardsPunishmentsLambdaQueryWrapper = Wrappers.lambdaQuery();
        ftbPersonnelsRewardsPunishmentsLambdaQueryWrapper.select(FtbPersonnelsRewardsPunishments::getRegularName, FtbPersonnelsRewardsPunishments::getIsRecorded);
        ftbPersonnelsRewardsPunishmentsLambdaQueryWrapper.eq(FtbPersonnelsRewardsPunishments::getId, ftbPenaltySubmissionDTO.getType());
        FtbPersonnelsRewardsPunishments ftbPersonnelsRewardsPunishments = ftbPersonnelsRewardsPunishmentsMapper.selectOne(ftbPersonnelsRewardsPunishmentsLambdaQueryWrapper);
        penaltySubmission.setTypeName(ftbPersonnelsRewardsPunishments.getRegularName());
        penaltySubmission.setIsRecorded(ftbPersonnelsRewardsPunishments.getIsRecorded());
        punishmentsApprovalMapper.insert(penaltySubmission);
        String punishmentsApprovalId = penaltySubmission.getId();
        if (CollUtil.isNotEmpty(ftbPenaltySubmissionDTO.getUserDtos())) {
            ActionResult<List<UserBoundVO>> userPrimaryBoundBatch = v2UserApi.getUserPrimaryBoundBatch(ftbPenaltySubmissionDTO.getUserDtos(), null);
            if (userPrimaryBoundBatch == null || CollUtil.isEmpty(userPrimaryBoundBatch.getData())) {
                throw new RuntimeException("获取人员信息失败");
            }
            Map<String, UserBoundVO> userIdMap = userPrimaryBoundBatch.getData().stream().collect(Collectors.toMap(UserBoundVO::getId, v -> v));
            ftbPenaltySubmissionDTO.getUserDtos().forEach(a -> {
                PunishmentsApprovalUser punishmentsApprovalUser = new PunishmentsApprovalUser();
                punishmentsApprovalUser.setUserId(a);
                punishmentsApprovalUser.setPunishmentsId(punishmentsApprovalId);
                // 默认组织、岗位、职等
                UserBoundVO partUserInfoVo = userIdMap.get(a);
                if (Objects.nonNull(partUserInfoVo)) {
                    punishmentsApprovalUser.setOrgName(partUserInfoVo.getOrganizeName());
                    punishmentsApprovalUser.setPostName(partUserInfoVo.getPositionName());
                    punishmentsApprovalUser.setGradesName(partUserInfoVo.getGradeName());
                }
                punishmentsApprovalUserMapper.insert(punishmentsApprovalUser);
            });
        }
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void penaltyPassed(FtbAwardPassedDTO ftbAwardPassedDTO) {
        LambdaUpdateWrapper<PunishmentsApproval> updater = Wrappers.lambdaUpdate();
        updater.eq(PunishmentsApproval::getFFlowid, ftbAwardPassedDTO.getTaskId());
        updater.set(PunishmentsApproval::getStatus, ftbAwardPassedDTO.getType());
        punishmentsApprovalMapper.update(new PunishmentsApproval(), updater);
    }

    /**
     * 校验当前用户是否办理入职
     *
     * @param userIds 用户 ID
     */
    private void validatePunishments(List<String> userIds) {
        LambdaQueryWrapper<FtbPersonnelsStaffRoster> queryWrapper1 = Wrappers.lambdaQuery();
        queryWrapper1.in(FtbPersonnelsStaffRoster::getUserId, userIds);
        queryWrapper1.eq(FtbPersonnelsStaffRoster::getEnabledMark, 0);
        List<FtbPersonnelsStaffRoster> staffStaffRosterList = staffRosterService.list(queryWrapper1);
        LambdaQueryWrapper<FtbPersonnelsStaffEmploymentApply> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.in(FtbPersonnelsStaffEmploymentApply::getUserId, userIds);
        queryWrapper.eq(FtbPersonnelsStaffEmploymentApply::getEnabledMark, 0);
        queryWrapper.eq(FtbPersonnelsStaffEmploymentApply::getIsNeedCheck, 0);
        queryWrapper.notIn(FtbPersonnelsStaffEmploymentApply::getCheckStatus, 2);
        List<FtbPersonnelsStaffEmploymentApply> one = staffEmploymentApplyService.list(queryWrapper);
        if (staffStaffRosterList.size() != userIds.size() && !one.isEmpty()) {
            String names = one.stream().map(FtbPersonnelsStaffEmploymentApply::getWorkerName).collect(Collectors.joining(","));
            throw new RuntimeException("当前选择人员" + names + "还未办理入职,无法提交!");
        }
    }

}
