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

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
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.CreatePresetCommentDto;
import com.competition.modules.biz.contest.entity.BizContest;
import com.competition.modules.biz.contest.mapper.ContestMapper;
import com.competition.modules.biz.review.entity.BizContestJudge;
import com.competition.modules.biz.review.entity.BizPresetComment;
import com.competition.modules.biz.review.mapper.ContestJudgeMapper;
import com.competition.modules.biz.review.mapper.PresetCommentMapper;
import com.competition.modules.biz.review.service.IPresetCommentService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

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

@Slf4j
@Service
@RequiredArgsConstructor
public class PresetCommentServiceImpl extends ServiceImpl<PresetCommentMapper, BizPresetComment> implements IPresetCommentService {

    private final PresetCommentMapper presetCommentMapper;
    private final ContestJudgeMapper contestJudgeMapper;
    private final ContestMapper contestMapper;

    @Override
    public BizPresetComment createComment(CreatePresetCommentDto dto, Long judgeId) {
        log.info("创建预设评语，评委ID：{}，赛事ID：{}", judgeId, dto.getContestId());

        BizPresetComment entity = new BizPresetComment();
        entity.setContestId(dto.getContestId());
        entity.setJudgeId(judgeId);
        entity.setContent(dto.getContent());
        entity.setScore(dto.getScore());
        entity.setSortOrder(dto.getSortOrder() != null ? dto.getSortOrder() : 0);
        entity.setUseCount(0);

        save(entity);
        log.info("预设评语创建成功，ID：{}", entity.getId());
        return entity;
    }

    @Override
    public List<Map<String, Object>> findAll(Long contestId, Long judgeId) {
        log.info("查询预设评语列表，赛事ID：{}，评委ID：{}", contestId, judgeId);

        LambdaQueryWrapper<BizPresetComment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(BizPresetComment::getValidState, 1);
        wrapper.eq(BizPresetComment::getJudgeId, judgeId);
        if (contestId != null) {
            wrapper.eq(BizPresetComment::getContestId, contestId);
        }
        wrapper.orderByAsc(BizPresetComment::getSortOrder);
        wrapper.orderByDesc(BizPresetComment::getUseCount);

        List<BizPresetComment> list = presetCommentMapper.selectList(wrapper);
        return list.stream().map(this::entityToMap).collect(Collectors.toList());
    }

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

        BizPresetComment entity = getById(id);
        if (entity == null) {
            throw BusinessException.of(ErrorCode.NOT_FOUND, "预设评语不存在");
        }
        if (!entity.getJudgeId().equals(judgeId)) {
            throw BusinessException.of(ErrorCode.FORBIDDEN, "无权查看此评语");
        }
        return entityToMap(entity);
    }

    @Override
    public BizPresetComment updateComment(Long id, CreatePresetCommentDto dto, Long judgeId) {
        log.info("更新预设评语，ID：{}，评委ID：{}", id, judgeId);

        BizPresetComment entity = getById(id);
        if (entity == null) {
            throw BusinessException.of(ErrorCode.NOT_FOUND, "预设评语不存在");
        }
        if (!entity.getJudgeId().equals(judgeId)) {
            throw BusinessException.of(ErrorCode.FORBIDDEN, "无权修改此评语");
        }

        if (dto.getContent() != null) {
            entity.setContent(dto.getContent());
        }
        if (dto.getScore() != null) {
            entity.setScore(dto.getScore());
        }
        if (dto.getSortOrder() != null) {
            entity.setSortOrder(dto.getSortOrder());
        }
        if (dto.getContestId() != null) {
            entity.setContestId(dto.getContestId());
        }

        updateById(entity);
        log.info("预设评语更新成功，ID：{}", id);
        return entity;
    }

    @Override
    public void removeComment(Long id, Long judgeId) {
        log.info("删除预设评语，ID：{}，评委ID：{}", id, judgeId);

        BizPresetComment entity = getById(id);
        if (entity == null) {
            throw BusinessException.of(ErrorCode.NOT_FOUND, "预设评语不存在");
        }
        if (!entity.getJudgeId().equals(judgeId)) {
            throw BusinessException.of(ErrorCode.FORBIDDEN, "无权删除此评语");
        }

        removeById(id);
        log.info("预设评语删除成功，ID：{}", id);
    }

    @Override
    public void batchDelete(List<Long> ids, Long judgeId) {
        log.info("批量删除预设评语，数量：{}，评委ID：{}", ids.size(), judgeId);

        LambdaQueryWrapper<BizPresetComment> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(BizPresetComment::getId, ids);
        wrapper.eq(BizPresetComment::getJudgeId, judgeId);

        remove(wrapper);
        log.info("批量删除预设评语完成");
    }

    @Override
    public void incrementUseCount(Long id, Long judgeId) {
        log.info("增加预设评语使用次数，ID：{}，评委ID：{}", id, judgeId);

        BizPresetComment entity = getById(id);
        if (entity == null) {
            throw BusinessException.of(ErrorCode.NOT_FOUND, "预设评语不存在");
        }
        if (!entity.getJudgeId().equals(judgeId)) {
            throw BusinessException.of(ErrorCode.FORBIDDEN, "无权操作此评语");
        }

        LambdaUpdateWrapper<BizPresetComment> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(BizPresetComment::getId, id);
        updateWrapper.setSql("use_count = use_count + 1");
        update(updateWrapper);
    }

    @Override
    public List<Map<String, Object>> getJudgeContests(Long judgeId) {
        log.info("查询评委关联赛事（预设评语视角），评委ID：{}", judgeId);

        LambdaQueryWrapper<BizContestJudge> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(BizContestJudge::getJudgeId, judgeId);
        wrapper.eq(BizContestJudge::getValidState, 1);

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

        return judgeRecords.stream().map(j -> {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("id", j.getContestId());
            // 查询赛事详情获取名称和状态
            BizContest contest = contestMapper.selectById(j.getContestId());
            if (contest != null) {
                map.put("contestName", contest.getContestName());
                map.put("contestState", contest.getContestState());
                map.put("status", contest.getStatus());
            }
            return map;
        }).collect(Collectors.toList());
    }

    @Override
    public Map<String, Object> syncComments(Long sourceContestId, List<Long> targetContestIds, Long judgeId) {
        log.info("同步预设评语，源赛事ID：{}，目标赛事数：{}，评委ID：{}", sourceContestId, targetContestIds.size(), judgeId);

        // 查询源赛事的评语
        LambdaQueryWrapper<BizPresetComment> sourceWrapper = new LambdaQueryWrapper<>();
        sourceWrapper.eq(BizPresetComment::getContestId, sourceContestId);
        sourceWrapper.eq(BizPresetComment::getJudgeId, judgeId);
        sourceWrapper.eq(BizPresetComment::getValidState, 1);
        List<BizPresetComment> sourceComments = presetCommentMapper.selectList(sourceWrapper);

        if (sourceComments.isEmpty()) {
            throw BusinessException.of(ErrorCode.BAD_REQUEST, "源赛事没有预设评语");
        }

        int created = 0;
        for (Long targetContestId : targetContestIds) {
            for (BizPresetComment source : sourceComments) {
                BizPresetComment copy = new BizPresetComment();
                copy.setContestId(targetContestId);
                copy.setJudgeId(judgeId);
                copy.setContent(source.getContent());
                copy.setScore(source.getScore());
                copy.setSortOrder(source.getSortOrder());
                copy.setUseCount(0);

                save(copy);
                created++;
            }
        }

        log.info("预设评语同步完成，新建数量：{}", created);

        Map<String, Object> result = new LinkedHashMap<>();
        result.put("message", "同步成功");
        result.put("count", created);
        return result;
    }

    // ====== 私有辅助方法 ======

    private Map<String, Object> entityToMap(BizPresetComment entity) {
        Map<String, Object> map = new LinkedHashMap<>();
        map.put("id", entity.getId());
        map.put("contestId", entity.getContestId());
        map.put("judgeId", entity.getJudgeId());
        map.put("content", entity.getContent());
        map.put("score", entity.getScore());
        map.put("sortOrder", entity.getSortOrder());
        map.put("useCount", entity.getUseCount());
        map.put("createTime", entity.getCreateTime());
        map.put("modifyTime", entity.getModifyTime());
        return map;
    }
}
