package com.lesingle.creation.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.lesingle.creation.dto.notice.CreateNoticeDTO;
import com.lesingle.creation.dto.notice.UpdateNoticeDTO;
import com.lesingle.creation.entity.Contest;
import com.lesingle.creation.entity.ContestNotice;
import com.lesingle.creation.common.exception.BusinessException;
import com.lesingle.creation.mapper.ContestNoticeMapper;
import com.lesingle.creation.mapper.ContestMapper;
import com.lesingle.creation.service.ContestNoticeService;
import com.lesingle.creation.vo.notice.NoticeVO;
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 ContestNoticeServiceImpl implements ContestNoticeService {

    private final ContestNoticeMapper contestNoticeMapper;
    private final ContestMapper contestMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public NoticeVO create(CreateNoticeDTO dto, Long creatorId) {
        // 验证活动是否存在
        Contest contest = contestMapper.selectById(dto.getContestId());
        if (contest == null) {
            throw new BusinessException("活动不存在");
        }

        ContestNotice notice = new ContestNotice();
        notice.setContestId(dto.getContestId());
        notice.setTitle(dto.getTitle());
        notice.setContent(dto.getContent());
        notice.setNoticeType(dto.getNoticeType());
        notice.setPriority(dto.getPriority());
        notice.setValidState(1);
        if (creatorId != null) {
            notice.setCreateBy(creatorId.toString());
        }

        contestNoticeMapper.insert(notice);
        log.info("创建公告成功，ID={}", notice.getId());

        return convertToVO(notice);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public NoticeVO update(Long id, UpdateNoticeDTO dto) {
        ContestNotice notice = contestNoticeMapper.selectById(id);
        if (notice == null) {
            throw new BusinessException("公告不存在");
        }

        notice.setTitle(dto.getTitle());
        notice.setContent(dto.getContent());
        if (dto.getPriority() != null) {
            notice.setPriority(dto.getPriority());
        }

        contestNoticeMapper.updateById(notice);
        log.info("更新公告成功，ID={}", id);

        return convertToVO(notice);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long id) {
        ContestNotice notice = contestNoticeMapper.selectById(id);
        if (notice == null) {
            throw new BusinessException("公告不存在");
        }

        notice.setValidState(2);
        contestNoticeMapper.updateById(notice);
        log.info("删除公告成功，ID={}", id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public NoticeVO publish(Long id) {
        ContestNotice notice = contestNoticeMapper.selectById(id);
        if (notice == null) {
            throw new BusinessException("公告不存在");
        }

        notice.setPublishTime(LocalDateTime.now());
        contestNoticeMapper.updateById(notice);
        log.info("发布公告成功，ID={}", id);

        return convertToVO(notice);
    }

    @Override
    public NoticeVO getDetail(Long id) {
        ContestNotice notice = contestNoticeMapper.selectById(id);
        if (notice == null) {
            throw new BusinessException("公告不存在");
        }
        return convertToVO(notice);
    }

    @Override
    public List<NoticeVO> listByContest(Long contestId) {
        List<ContestNotice> notices = contestNoticeMapper.selectList(new LambdaQueryWrapper<ContestNotice>()
                .eq(ContestNotice::getContestId, contestId)
                .eq(ContestNotice::getValidState, 1)
                .eq(ContestNotice::getDeleted, 0)
                .orderByDesc(ContestNotice::getPriority)
                .orderByDesc(ContestNotice::getPublishTime));

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

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

    private NoticeVO convertToVO(ContestNotice notice) {
        NoticeVO vo = new NoticeVO();
        vo.setId(notice.getId());
        vo.setContestId(notice.getContestId());
        vo.setTitle(notice.getTitle());
        vo.setContent(notice.getContent());
        vo.setNoticeType(notice.getNoticeType());
        vo.setPriority(notice.getPriority());
        vo.setPublishTime(notice.getPublishTime());
        vo.setValidState(notice.getValidState());

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

        return vo;
    }
}
