package com.lesingle.creation.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.lesingle.creation.dto.result.CreateResultDTO;
import com.lesingle.creation.entity.*;
import com.lesingle.creation.common.exception.BusinessException;
import com.lesingle.creation.mapper.*;
import com.lesingle.creation.service.ContestResultService;
import com.lesingle.creation.vo.result.ResultVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 竞赛结果服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ContestResultServiceImpl implements ContestResultService {

    private final ContestResultMapper resultMapper;
    private final ContestMapper contestMapper;
    private final ContestWorkMapper workMapper;
    private final ContestRegistrationMapper registrationMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVO create(CreateResultDTO dto, Long creatorId) {
        // 验证作品是否存在
        ContestWork work = workMapper.selectById(dto.getWorkId());
        if (work == null) {
            throw new BusinessException("作品不存在");
        }

        // 验证报名是否存在
        ContestRegistration registration = registrationMapper.selectById(dto.getRegistrationId());
        if (registration == null) {
            throw new BusinessException("报名记录不存在");
        }

        // 检查结果是否已存在
        ContestResult existing = resultMapper.selectOne(new LambdaQueryWrapper<ContestResult>()
                .eq(ContestResult::getWorkId, dto.getWorkId())
                .eq(ContestResult::getDeleted, 0));
        if (existing != null) {
            throw new BusinessException("该作品已有结果记录");
        }

        ContestResult result = new ContestResult();
        result.setContestId(work.getContestId());
        result.setWorkId(dto.getWorkId());
        result.setRegistrationId(dto.getRegistrationId());
        result.setTotalScore(dto.getTotalScore());
        result.setAwardLevel(dto.getAwardLevel());
        result.setDescription(dto.getDescription());
        result.setIsWinner(dto.getIsWinner());
        result.setPublicState("pending");
        if (creatorId != null) {
            result.setCreateBy(creatorId.toString());
        }

        resultMapper.insert(result);
        log.info("创建竞赛结果成功，ID={}", result.getId());

        return convertToVO(result);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVO update(Long id, CreateResultDTO dto) {
        ContestResult result = resultMapper.selectById(id);
        if (result == null) {
            throw new BusinessException("竞赛结果不存在");
        }

        result.setTotalScore(dto.getTotalScore());
        result.setAwardLevel(dto.getAwardLevel());
        result.setDescription(dto.getDescription());
        result.setIsWinner(dto.getIsWinner());

        resultMapper.updateById(result);
        log.info("更新竞赛结果成功，ID={}", id);

        return convertToVO(result);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVO publish(Long id) {
        ContestResult result = resultMapper.selectById(id);
        if (result == null) {
            throw new BusinessException("竞赛结果不存在");
        }

        result.setPublicState("published");
        result.setPublishTime(LocalDateTime.now());
        resultMapper.updateById(result);
        log.info("发布竞赛结果成功，ID={}", id);

        return convertToVO(result);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long id) {
        ContestResult result = resultMapper.selectById(id);
        if (result == null) {
            throw new BusinessException("竞赛结果不存在");
        }
        resultMapper.deleteById(id);
        log.info("删除竞赛结果成功，ID={}", id);
    }

    @Override
    public ResultVO getDetail(Long id) {
        ContestResult result = resultMapper.selectById(id);
        if (result == null) {
            throw new BusinessException("竞赛结果不存在");
        }
        return convertToVO(result);
    }

    @Override
    public List<ResultVO> listByContest(Long contestId) {
        List<ContestResult> results = resultMapper.selectList(new LambdaQueryWrapper<ContestResult>()
                .eq(ContestResult::getContestId, contestId)
                .eq(ContestResult::getDeleted, 0)
                .orderByDesc(ContestResult::getTotalScore));

        return results.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public List<ResultVO> listWinners(Long contestId) {
        List<ContestResult> results = resultMapper.selectList(new LambdaQueryWrapper<ContestResult>()
                .eq(ContestResult::getContestId, contestId)
                .eq(ContestResult::getIsWinner, true)
                .eq(ContestResult::getDeleted, 0)
                .orderByDesc(ContestResult::getTotalScore));

        return results.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    // ========== 转换方法 ==========

    private ResultVO convertToVO(ContestResult result) {
        ResultVO vo = new ResultVO();
        vo.setId(result.getId());
        vo.setContestId(result.getContestId());
        vo.setWorkId(result.getWorkId());
        vo.setRegistrationId(result.getRegistrationId());
        vo.setTotalScore(result.getTotalScore());
        vo.setAwardLevel(result.getAwardLevel());
        vo.setDescription(result.getDescription());
        vo.setIsWinner(result.getIsWinner());
        vo.setPublicState(result.getPublicState());
        vo.setPublishTime(result.getPublishTime());

        // 获取活动名称
        Contest contest = contestMapper.selectById(result.getContestId());
        if (contest != null) {
            vo.setContestName(contest.getContestName());
        }

        // 获取作品标题
        ContestWork work = workMapper.selectById(result.getWorkId());
        if (work != null) {
            vo.setWorkTitle(work.getTitle());
        }

        // 获取参赛者姓名
        ContestRegistration registration = registrationMapper.selectById(result.getRegistrationId());
        if (registration != null) {
            vo.setParticipantName(registration.getAccountName());
        }

        return vo;
    }
}
