package com.ruoyi.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.domain.ReviewSceneChangeTask;
import com.ruoyi.domain.ReviewSceneChangeTaskUserRelation;
import com.ruoyi.service.ReviewSceneChangeTaskService;
import com.ruoyi.mapper.ReviewSceneChangeTaskMapper;
import com.ruoyi.service.ReviewSceneChangeTaskUserRelationService;
import com.ruoyi.service.ReviewSceneService;
import com.ruoyi.service.ReviewTaskInboxService;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.web.request.ReviewSceneChangeTaskFindCreateRequest;
import com.ruoyi.web.request.ReviewSceneChangeTaskFindFinishRequest;
import com.ruoyi.web.request.ReviewSceneChangeTaskFindPendingRequest;
import com.ruoyi.web.request.ReviewSceneChangeTaskPassRequest;
import com.ruoyi.web.response.ReviewSceneChangeTaskResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
* @author wangfei
* @description 针对表【t_review_scene_change_task(审查场景变更任务)】的数据库操作Service实现
* @createDate 2023-12-14 14:28:17
*/
@Transactional
@Service
public class ReviewSceneChangeTaskServiceImpl extends ServiceImpl<ReviewSceneChangeTaskMapper, ReviewSceneChangeTask> implements ReviewSceneChangeTaskService {

    @Autowired
    private ReviewSceneChangeTaskUserRelationService reviewSceneChangeTaskUserRelationService;

    @Autowired
    private ReviewSceneChangeTaskService reviewSceneChangeTaskService;

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private ReviewSceneService reviewSceneService;

    @Autowired
    private ReviewTaskInboxService reviewTaskInboxService;

    @Autowired
    private ReviewSceneChangeTaskMapper reviewSceneChangeTaskMapper;

    @Override
    public void create(ReviewSceneChangeTask reviewSceneChangeTask) {

        // 获取当前登陆人
        SysUser loginUser = SecurityUtils.getLoginUser().getUser();

        // 创建任务
        reviewSceneChangeTask
                .setTaskInitiator(loginUser.getNickName())
                .setTaskInitiatorDept(loginUser.getDept().getDeptName())
                .setTaskInitiatorId(loginUser.getUserId())
                .setTaskStatus(ReviewSceneChangeTask.STATUS_PENDING)
                .setTaskBeginTime(new Date());

        // 保存任务
        save(reviewSceneChangeTask);

        // 绑定审核人
        List<SysUser> sysUsers = sysUserService.selectUserListByRoleId(ReviewSceneChangeTask.REVIEW_ROLE_ID);
        List<ReviewSceneChangeTaskUserRelation> relations = new ArrayList();
        for(SysUser sysUser : sysUsers) {
            ReviewSceneChangeTaskUserRelation relation = new ReviewSceneChangeTaskUserRelation()
                    .setTaskId(reviewSceneChangeTask.getId())
                    .setUserId(sysUser.getUserId())
                    .setName(sysUser.getNickName())
                    .setDept(sysUser.getDept().getDeptName());

            relations.add(relation);
        }

        reviewSceneChangeTaskUserRelationService.saveBatch(relations);
    }

    @Override
    public void pass(Long taskId, String comment) {
        doProcess(taskId, comment, ReviewSceneChangeTask.RESULT_PASS);
    }



    @Override
    public void reject(Long taskId, String comment) {
        doProcess(taskId, comment, ReviewSceneChangeTask.RESULT_REJECT);
    }

    @Override
    public void audit(ReviewSceneChangeTaskPassRequest request) {
        if (request.getPassed().equals(ReviewSceneChangeTask.PASSED_REJECT)) {
            doProcess(request.getTaskId(), request.getComment(), ReviewSceneChangeTask.RESULT_REJECT);
        } else if(request.getPassed().equals(ReviewSceneChangeTask.PASSED_PASS)){
            doProcess(request.getTaskId(), request.getComment(), ReviewSceneChangeTask.RESULT_PASS);
        } else {
            throw new ServiceException("审核状态不正确",HttpStatus.ERROR);
        }
    }

    public void doProcess(Long taskId, String comment, String decision) {

        ReviewSceneChangeTask task = getById(taskId);
        checkTaskStatus(task.getTaskStatus());

        // 获取当前登陆人
        SysUser loginUser = SecurityUtils.getLoginUser().getUser();

        // 1.获取该任务的所有审批人
        // 2.获取当前用户对应的审批信息
        // 3.保存评审意见
        List<ReviewSceneChangeTaskUserRelation> relations = reviewSceneChangeTaskUserRelationService.findListByTaskId(taskId);
        for(ReviewSceneChangeTaskUserRelation relation : relations) {
            if(relation.getUserId().equals(loginUser.getUserId())) {
                relation.setDecision(decision);
                relation.setComment(comment);
                relation.setDecisionTime(new Date());
                reviewSceneChangeTaskUserRelationService.updateById(relation);
                break;
            }
        }

        // 判断当前任务是否全员审核完毕,如果是则将当前任务设置为完成。
        if(isFinish(relations)) {

            task.setTaskStatus(ReviewSceneChangeTask.STATUS_FINISH);
            task.setTaskEndTime(new Date());
            task.setTaskResult(isPassed(relations) ? ReviewSceneChangeTaskUserRelation.DECISION_PASS : ReviewSceneChangeTaskUserRelation.DECISION_REJECT);

            reviewSceneChangeTaskService.updateById(task);

            // 如果当前任务为全员通过,则对审查标准文件进行更新,同时向受到变更影响的问卷的“收件箱”表中写入数据,记录变更用于提醒用户。
            if(task.getTaskResult().equals(ReviewSceneChangeTaskUserRelation.DECISION_PASS)) {
                // 更新审核标准
                reviewSceneService.change(task);

                // 通知受影响的问卷
                reviewTaskInboxService.saveNotify(taskId, task.getType());
            }
        }

    }

    @Override
    public void close(Long taskId) {
    }

    @Override
    public List<ReviewSceneChangeTask> findLastChangeByTaskId(Long taskId) {
        return reviewSceneChangeTaskMapper.findLastChangeByTaskId(taskId);
    }

    private void checkTaskStatus(String status) {
        if(status != null && ReviewSceneChangeTask.STATUS_FINISH.equals(status)) {
            throw new ServiceException("不能处理一个已经完成的任务", HttpStatus.ERROR);
        }
        if(status != null && ReviewSceneChangeTask.STATUS_CLOSE.equals(status)) {
            throw new ServiceException("不能处理一个已经关闭的任务", HttpStatus.ERROR);
        }
    }

    /**
     * 检查当前任务是否完成(所有审核人都发表了意见)
     * @param relations
     * @return
     */
    private boolean isFinish(List<ReviewSceneChangeTaskUserRelation> relations) {

        for(ReviewSceneChangeTaskUserRelation relation : relations) {
            String decision = relation.getDecision();
            if(decision == null || "".equals(decision)) {
                return false;
            }
        }

        return true;
    }

    /**
     * 检查是否全员通过
     * @param relations
     * @return
     */
    private boolean isPassed(List<ReviewSceneChangeTaskUserRelation> relations) {

        for(ReviewSceneChangeTaskUserRelation relation : relations) {
            if(relation.getDecision().equals(ReviewSceneChangeTaskUserRelation.DECISION_REJECT)) {
                return false;
            }
        }

        return true;
    }

    /**
     * 根据用户ID查询待办列表
     * @param userId
     * @return
     */
    @Override
    public List<ReviewSceneChangeTaskResponse> findPendingListByUserId(Long userId, ReviewSceneChangeTaskFindPendingRequest request) {
        List<ReviewSceneChangeTaskResponse> reviewSceneChangeTask = reviewSceneChangeTaskMapper.findPendingListByUserId(userId,request);
        return reviewSceneChangeTask;
    }

    /**
     * 根据用户ID查询已办列表
     * @param userId
     * @return
     */
    @Override
    public List<ReviewSceneChangeTaskResponse> findFinishListByUserId(Long userId, ReviewSceneChangeTaskFindFinishRequest request) {
        List<ReviewSceneChangeTaskResponse> reviewSceneChangeTask = reviewSceneChangeTaskMapper.findFinishListByUserId(userId,request);
        return reviewSceneChangeTask;
    }

    /**
     * 根据用户ID查询已办列表
     * @param userId
     * @return
     */
    @Override
    public List<ReviewSceneChangeTask> findCreateListByUserId(Long userId, ReviewSceneChangeTaskFindCreateRequest request) {
        List<ReviewSceneChangeTask> reviewSceneChangeTask = reviewSceneChangeTaskMapper.findCreateListByUserId(userId,request);
        return reviewSceneChangeTask;
    }

}