package com.lesingle.creation.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.lesingle.creation.dto.reviewrule.CreateReviewDimensionDTO;
import com.lesingle.creation.dto.reviewrule.CreateReviewRuleDTO;
import com.lesingle.creation.entity.ContestReviewDimension;
import com.lesingle.creation.entity.ContestReviewRule;
import com.lesingle.creation.common.exception.BusinessException;
import com.lesingle.creation.mapper.ContestReviewDimensionMapper;
import com.lesingle.creation.mapper.ContestReviewRuleMapper;
import com.lesingle.creation.service.ContestReviewRuleService;
import com.lesingle.creation.vo.reviewrule.ReviewDimensionVO;
import com.lesingle.creation.vo.reviewrule.ReviewRuleVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * 竞赛评审规则服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ContestReviewRuleServiceImpl implements ContestReviewRuleService {

    private final ContestReviewRuleMapper reviewRuleMapper;
    private final ContestReviewDimensionMapper dimensionMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ReviewRuleVO create(CreateReviewRuleDTO dto, Long tenantId, Long creatorId) {
        ContestReviewRule rule = new ContestReviewRule();
        rule.setTenantId(tenantId);
        rule.setRuleName(dto.getRuleName());
        rule.setRuleType(dto.getRuleType());
        rule.setTotalScore(dto.getTotalScore());
        rule.setDescription(dto.getDescription());
        if (creatorId != null) {
            rule.setCreateBy(creatorId.toString());
        }

        reviewRuleMapper.insert(rule);
        log.info("创建评审规则成功，ID={}", rule.getId());

        return convertToVO(rule);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long id) {
        ContestReviewRule rule = reviewRuleMapper.selectById(id);
        if (rule == null) {
            throw new BusinessException("评审规则不存在");
        }
        reviewRuleMapper.deleteById(id);
        log.info("删除评审规则成功，ID={}", id);
    }

    @Override
    public ReviewRuleVO getDetail(Long id) {
        ContestReviewRule rule = reviewRuleMapper.selectById(id);
        if (rule == null) {
            throw new BusinessException("评审规则不存在");
        }
        return convertToVO(rule);
    }

    @Override
    public List<ReviewRuleVO> list(Long tenantId) {
        List<ContestReviewRule> rules = reviewRuleMapper.selectList(new LambdaQueryWrapper<ContestReviewRule>()
                .eq(ContestReviewRule::getTenantId, tenantId)
                .eq(ContestReviewRule::getDeleted, 0)
                .orderByDesc(ContestReviewRule::getCreateTime));

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

    @Override
    public List<ReviewRuleVO> listForSelect(Long tenantId) {
        List<ContestReviewRule> rules = reviewRuleMapper.selectList(new LambdaQueryWrapper<ContestReviewRule>()
                .eq(ContestReviewRule::getTenantId, tenantId)
                .eq(ContestReviewRule::getDeleted, 0)
                .eq(ContestReviewRule::getValidState, 1)
                .orderByDesc(ContestReviewRule::getCreateTime));

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

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ReviewRuleVO addDimension(CreateReviewDimensionDTO dto) {
        ContestReviewRule rule = reviewRuleMapper.selectById(dto.getRuleId());
        if (rule == null) {
            throw new BusinessException("评审规则不存在");
        }

        ContestReviewDimension dimension = new ContestReviewDimension();
        dimension.setRuleId(dto.getRuleId());
        dimension.setDimensionName(dto.getDimensionName());
        dimension.setDescription(dto.getDescription());
        dimension.setWeight(dto.getWeight());
        dimension.setMaxScore(dto.getMaxScore());
        dimension.setSort(dto.getSort());

        dimensionMapper.insert(dimension);
        log.info("添加评审维度成功，ID={}", dimension.getId());

        return convertToVO(rule);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteDimension(Long id) {
        ContestReviewDimension dimension = dimensionMapper.selectById(id);
        if (dimension == null) {
            throw new BusinessException("评审维度不存在");
        }
        dimensionMapper.deleteById(id);
        log.info("删除评审维度成功，ID={}", id);
    }

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

    private ReviewRuleVO convertToVO(ContestReviewRule rule) {
        ReviewRuleVO vo = new ReviewRuleVO();
        vo.setId(rule.getId());
        vo.setTenantId(rule.getTenantId());
        vo.setRuleName(rule.getRuleName());
        vo.setRuleType(rule.getRuleType());
        vo.setTotalScore(rule.getTotalScore());
        vo.setDescription(rule.getDescription());
        vo.setCreateTime(rule.getCreateTime());

        // 获取维度列表
        List<ContestReviewDimension> dimensions = dimensionMapper.selectList(
                new LambdaQueryWrapper<ContestReviewDimension>()
                        .eq(ContestReviewDimension::getRuleId, rule.getId())
                        .eq(ContestReviewDimension::getDeleted, 0)
                        .orderByAsc(ContestReviewDimension::getSort));

        List<ReviewDimensionVO> dimensionVOs = dimensions.stream()
                .map(this::convertToDimensionVO)
                .collect(Collectors.toList());
        vo.setDimensions(dimensionVOs);

        return vo;
    }

    private ReviewDimensionVO convertToDimensionVO(ContestReviewDimension dimension) {
        ReviewDimensionVO vo = new ReviewDimensionVO();
        vo.setId(dimension.getId());
        vo.setRuleId(dimension.getRuleId());
        vo.setDimensionName(dimension.getDimensionName());
        vo.setDescription(dimension.getDescription());
        vo.setWeight(dimension.getWeight());
        vo.setMaxScore(dimension.getMaxScore());
        vo.setSort(dimension.getSort());
        return vo;
    }
}
