package com.competition.modules.biz.review.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.competition.common.enums.ErrorCode;
import com.competition.common.exception.BusinessException;
import com.competition.modules.biz.review.dto.ContestJudgesForContestVo;
import com.competition.modules.biz.review.entity.BizContestJudge;
import com.competition.modules.biz.review.entity.BizContestWorkJudgeAssignment;
import com.competition.modules.biz.review.mapper.ContestJudgeMapper;
import com.competition.modules.biz.review.mapper.ContestWorkJudgeAssignmentMapper;
import com.competition.modules.biz.review.service.IContestJudgeService;
import com.competition.modules.sys.entity.SysTenant;
import com.competition.modules.sys.entity.SysUser;
import com.competition.modules.sys.mapper.SysTenantMapper;
import com.competition.modules.sys.mapper.SysUserMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class ContestJudgeServiceImpl extends ServiceImpl<ContestJudgeMapper, BizContestJudge> implements IContestJudgeService {

    private final ContestJudgeMapper contestJudgeMapper;
    private final ContestWorkJudgeAssignmentMapper assignmentMapper;
    private final SysUserMapper sysUserMapper;
    private final SysTenantMapper sysTenantMapper;

    @Override
    public BizContestJudge createJudge(Long contestId, Long judgeId, String specialty, BigDecimal weight, String description) {
        log.info("添加评委，赛事ID：{}，评委用户ID：{}", contestId, judgeId);

        // 校验是否重复
        LambdaQueryWrapper<BizContestJudge> dupWrapper = new LambdaQueryWrapper<>();
        dupWrapper.eq(BizContestJudge::getContestId, contestId);
        dupWrapper.eq(BizContestJudge::getJudgeId, judgeId);
        dupWrapper.eq(BizContestJudge::getValidState, 1);
        if (count(dupWrapper) > 0) {
            throw BusinessException.of(ErrorCode.BAD_REQUEST, "该评委已添加到此赛事");
        }

        BizContestJudge entity = new BizContestJudge();
        entity.setContestId(contestId);
        entity.setJudgeId(judgeId);
        entity.setSpecialty(specialty);
        entity.setWeight(weight != null ? weight : BigDecimal.ONE);
        entity.setDescription(description);

        save(entity);
        log.info("评委添加成功，ID：{}", entity.getId());
        return entity;
    }

    @Override
    public ContestJudgesForContestVo findByContest(Long contestId) {
        log.info("查询赛事评委列表，赛事ID：{}", contestId);

        // 获取平台评委租户 ID
        Long judgeTenantId = getJudgeTenantId();

        // 1. 查询已显式分配的评委
        LambdaQueryWrapper<BizContestJudge> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(BizContestJudge::getContestId, contestId);
        wrapper.eq(BizContestJudge::getValidState, 1);
        wrapper.orderByAsc(BizContestJudge::getCreateTime);

        List<BizContestJudge> judges = contestJudgeMapper.selectList(wrapper);

        // 收集所有需要查询的用户 ID（已分配评委）
        Set<Long> assignedJudgeIds = judges.stream().map(BizContestJudge::getJudgeId).collect(Collectors.toSet());

        // 2. 查询平台评委（自动对所有赛事可用）
        List<SysUser> platformJudges = new ArrayList<>();
        if (judgeTenantId != null) {
            LambdaQueryWrapper<SysUser> platformWrapper = new LambdaQueryWrapper<>();
            platformWrapper.eq(SysUser::getTenantId, judgeTenantId);
            platformWrapper.eq(SysUser::getStatus, "enabled");
            platformJudges = sysUserMapper.selectList(platformWrapper);
        }

        // 平台评委中去掉已显式分配的（避免重复）
        Set<Long> platformOnlyIds = platformJudges.stream()
                .map(SysUser::getId)
                .filter(id -> !assignedJudgeIds.contains(id))
                .collect(Collectors.toSet());

        // 合并所有需要查询的用户 ID
        Set<Long> allUserIds = new HashSet<>(assignedJudgeIds);
        allUserIds.addAll(platformOnlyIds);

        // 批量查询用户信息
        Map<Long, SysUser> userMap = new HashMap<>();
        if (!allUserIds.isEmpty()) {
            List<SysUser> users = sysUserMapper.selectBatchIds(allUserIds);
            for (SysUser user : users) {
                userMap.put(user.getId(), user);
            }
        }

        // 批量查询每个评委在该赛事下的已分配作品数
        Map<Long, Long> assignedCountMap = new HashMap<>();
        for (Long judgeId : allUserIds) {
            LambdaQueryWrapper<BizContestWorkJudgeAssignment> assignWrapper = new LambdaQueryWrapper<>();
            assignWrapper.eq(BizContestWorkJudgeAssignment::getContestId, contestId);
            assignWrapper.eq(BizContestWorkJudgeAssignment::getJudgeId, judgeId);
            assignedCountMap.put(judgeId, assignmentMapper.selectCount(assignWrapper));
        }

        List<Map<String, Object>> assigned = new ArrayList<>();
        List<Map<String, Object>> implicitPool = new ArrayList<>();

        // 构建已显式分配的评委数据
        for (BizContestJudge j : judges) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("id", j.getId());
            map.put("contestId", j.getContestId());
            map.put("judgeId", j.getJudgeId());
            map.put("specialty", j.getSpecialty());
            map.put("weight", j.getWeight());
            map.put("description", j.getDescription());
            map.put("createTime", j.getCreateTime());
            map.put("assignedCount", assignedCountMap.getOrDefault(j.getJudgeId(), 0L));

            SysUser user = userMap.get(j.getJudgeId());
            if (user != null) {
                map.put("judgeName", user.getNickname());
                map.put("judgeUsername", user.getUsername());
                map.put("tenantId", user.getTenantId());
                map.put("status", user.getStatus());
                map.put("organization", user.getOrganization());
                map.put("isPlatform", judgeTenantId != null && judgeTenantId.equals(user.getTenantId()));
            } else {
                map.put("isPlatform", false);
            }
            assigned.add(map);
        }

        // 未显式分配的平台评委（隐式池）
        for (SysUser platformJudge : platformJudges) {
            if (assignedJudgeIds.contains(platformJudge.getId())) {
                continue; // 已在显式分配列表中，跳过
            }
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("id", null);
            map.put("contestId", contestId);
            map.put("judgeId", platformJudge.getId());
            map.put("specialty", null);
            map.put("weight", null);
            map.put("description", null);
            map.put("createTime", null);
            map.put("assignedCount", assignedCountMap.getOrDefault(platformJudge.getId(), 0L));
            map.put("judgeName", platformJudge.getNickname());
            map.put("judgeUsername", platformJudge.getUsername());
            map.put("tenantId", platformJudge.getTenantId());
            map.put("status", platformJudge.getStatus());
            map.put("organization", platformJudge.getOrganization());
            map.put("isPlatform", true);
            implicitPool.add(map);
        }

        ContestJudgesForContestVo vo = new ContestJudgesForContestVo();
        vo.setAssigned(assigned);
        vo.setImplicitPool(implicitPool);
        return vo;
    }

    /**
     * 获取平台评委租户 ID
     */
    private Long getJudgeTenantId() {
        LambdaQueryWrapper<SysTenant> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysTenant::getCode, "judge");
        SysTenant tenant = sysTenantMapper.selectOne(wrapper);
        return tenant != null ? tenant.getId() : null;
    }

    @Override
    public Map<String, Object> findDetail(Long id) {
        log.info("查询评委详情，ID：{}", id);

        BizContestJudge entity = getById(id);
        if (entity == null) {
            throw BusinessException.of(ErrorCode.NOT_FOUND, "评委记录不存在");
        }

        Map<String, Object> map = new LinkedHashMap<>();
        map.put("id", entity.getId());
        map.put("contestId", entity.getContestId());
        map.put("judgeId", entity.getJudgeId());
        map.put("specialty", entity.getSpecialty());
        map.put("weight", entity.getWeight());
        map.put("description", entity.getDescription());
        map.put("createTime", entity.getCreateTime());

        SysUser user = sysUserMapper.selectById(entity.getJudgeId());
        if (user != null) {
            map.put("judgeName", user.getNickname());
            map.put("judgeUsername", user.getUsername());
        }

        return map;
    }

    @Override
    public BizContestJudge updateJudge(Long id, String specialty, BigDecimal weight, String description) {
        log.info("更新评委信息，ID：{}", id);

        BizContestJudge entity = getById(id);
        if (entity == null) {
            throw BusinessException.of(ErrorCode.NOT_FOUND, "评委记录不存在");
        }

        if (specialty != null) {
            entity.setSpecialty(specialty);
        }
        if (weight != null) {
            entity.setWeight(weight);
        }
        if (description != null) {
            entity.setDescription(description);
        }

        updateById(entity);
        log.info("评委信息更新成功，ID：{}", id);
        return entity;
    }

    @Override
    public void removeJudge(Long id) {
        log.info("删除评委，ID：{}", id);
        removeById(id);
        log.info("评委删除成功，ID：{}", id);
    }
}
