package com.hz.pm.api.meeting.manage;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ningdatech.basic.exception.BizException;
import com.ningdatech.basic.util.CollUtils;
import com.ningdatech.basic.util.ValidUtil;
import com.ningdatech.cache.lock.DistributedLock;
import com.hz.pm.api.meeting.entity.domain.Meeting;
import com.hz.pm.api.meeting.entity.domain.MeetingExpert;
import com.hz.pm.api.meeting.entity.domain.MeetingExpertJudge;
import com.hz.pm.api.meeting.entity.enumeration.ExpertAttendStatusEnum;
import com.hz.pm.api.meeting.entity.enumeration.ExpertJudgeEnum;
import com.hz.pm.api.meeting.entity.enumeration.MeetingStatusEnum;
import com.hz.pm.api.meeting.entity.req.MeetingExpertJudgeReq;
import com.hz.pm.api.meeting.entity.req.MeetingExpertJudgeReq.Attend;
import com.hz.pm.api.meeting.service.IMeetingExpertJudgeService;
import com.hz.pm.api.meeting.service.IMeetingExpertService;
import com.hz.pm.api.meeting.service.IMeetingService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * <p>
 * MeetingExpertJudgeManage
 * </p>
 *
 * @author WendyYang
 * @since 2023/7/31
 **/
@Component
@AllArgsConstructor
public class MeetingExpertJudgeManage {

    private final IMeetingExpertJudgeService expertJudgeService;
    private final IMeetingExpertService meetingExpertService;
    private final IMeetingService meetingService;
    private final DistributedLock distributedLock;

    private MeetingExpertJudge getMeetingExpertJudge(Long meetingExpertId) {
        LambdaQueryWrapper<MeetingExpertJudge> query = Wrappers.lambdaQuery(MeetingExpertJudge.class)
                .eq(MeetingExpertJudge::getMeetingExpertId, meetingExpertId);
        return expertJudgeService.getOne(query);
    }

    public void saveExpertJudge(MeetingExpertJudgeReq req) {
        String key = "lock_expert_judge:" + req.getMeetingExpertId();
        if (!distributedLock.lock(key, 3)) {
            throw BizException.wrap("履职评价失败，请重试");
        }
        try {
            if (!ExpertJudgeEnum.AttendStatus.ABSENT.eq(req.getAttended())) {
                Map<String, String> validMap = ValidUtil.valid(req, Attend.class);
                if (!validMap.isEmpty()) {
                    String errMsg = CollUtils.joinByComma(validMap.values());
                    throw BizException.wrap(errMsg);
                }
            }
            // 会议状态校验
            Meeting meeting = meetingService.getById(req.getMeetingId());
            if (meeting == null || MeetingStatusEnum.CANCELED.eq(meeting.getStatus())) {
                throw BizException.wrap("会议不存在或已取消");
            }
            // 专家抽取状态校验
            MeetingExpert expert = meetingExpertService.getById(req.getMeetingExpertId());
            if (expert == null || (ExpertAttendStatusEnum.AGREED.eq(expert.getStatus())
                    && ExpertAttendStatusEnum.ON_LEAVE.eq(expert.getStatus()))) {
                throw BizException.wrap("未被抽中专家无法进行履职评价");
            }
            // 智能履职评价一次
            MeetingExpertJudge judge = getMeetingExpertJudge(req.getMeetingExpertId());
            if (judge != null) {
                throw BizException.wrap("履职评价已提交");
            }
            MeetingExpertJudge entity = BeanUtil.copyProperties(req, MeetingExpertJudge.class);
            entity.setExpertId(expert.getExpertId());
            expertJudgeService.save(entity);
        } finally {
            distributedLock.releaseLock(key);
        }
    }

    public MeetingExpertJudgeReq expertJudgeDetail(Long meetingExpertId) {
        MeetingExpertJudge judge = expertJudgeService.getByMeetingExpertId(meetingExpertId);
        if (judge == null) {
            throw BizException.wrap("履职评价未提交");
        }
        return BeanUtil.copyProperties(judge, MeetingExpertJudgeReq.class);
    }

}
