package com.lesingle.creation.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lesingle.creation.dto.grade.CreateGradeDTO;
import com.lesingle.creation.dto.grade.UpdateGradeDTO;
import com.lesingle.creation.entity.Grade;
import com.lesingle.creation.common.exception.BusinessException;
import com.lesingle.creation.mapper.GradeMapper;
import com.lesingle.creation.service.GradeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lesingle.creation.vo.grade.GradeVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 年级服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class GradeServiceImpl extends ServiceImpl<GradeMapper, Grade> implements GradeService {

    private final GradeMapper gradeMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public GradeVO create(CreateGradeDTO dto, Long tenantId, Long creatorId) {
        // 检查年级编码是否已存在
        Grade existing = gradeMapper.selectByCode(tenantId, dto.getCode());
        if (existing != null) {
            throw new BusinessException("年级编码已存在");
        }

        // 检查年级级别是否已存在
        Grade existingByLevel = this.getOne(new LambdaQueryWrapper<Grade>()
                .eq(Grade::getTenantId, tenantId)
                .eq(Grade::getLevel, dto.getLevel())
                .eq(Grade::getDeleted, 0));
        if (existingByLevel != null) {
            throw new BusinessException("年级级别已存在");
        }

        Grade grade = new Grade();
        grade.setTenantId(tenantId);
        grade.setName(dto.getName());
        grade.setCode(dto.getCode());
        grade.setLevel(dto.getLevel());
        grade.setDescription(dto.getDescription());
        grade.setValidState(1);

        gradeMapper.insert(grade);
        log.info("创建年级成功，ID={}, 名称={}", grade.getId(), dto.getName());

        return convertToVO(grade);
    }

    @Override
    public Page<GradeVO> pageQuery(Integer pageNum, Integer pageSize, Long tenantId) {
        Page<Grade> page = new Page<>(pageNum, pageSize);

        LambdaQueryWrapper<Grade> wrapper = new LambdaQueryWrapper<Grade>()
                .eq(Grade::getTenantId, tenantId)
                .eq(Grade::getDeleted, 0)
                .orderByAsc(Grade::getLevel);

        Page<Grade> resultPage = this.page(page, wrapper);

        Page<GradeVO> voPage = new Page<>(resultPage.getCurrent(), resultPage.getSize(), resultPage.getTotal());
        voPage.setRecords(resultPage.getRecords().stream().map(this::convertToVO).toList());
        return voPage;
    }

    @Override
    public GradeVO getDetail(Long id, Long tenantId) {
        Grade grade = this.getById(id);
        if (grade == null || !grade.getTenantId().equals(tenantId)) {
            throw new BusinessException("年级不存在");
        }
        return convertToVO(grade);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public GradeVO update(Long id, UpdateGradeDTO dto, Long tenantId, Long modifierId) {
        Grade grade = this.getById(id);
        if (grade == null || !grade.getTenantId().equals(tenantId)) {
            throw new BusinessException("年级不存在");
        }

        if (dto.getName() != null) {
            grade.setName(dto.getName());
        }
        if (dto.getCode() != null) {
            // 检查新编码是否已被其他年级使用
            Grade existing = gradeMapper.selectByCode(tenantId, dto.getCode());
            if (existing != null && !existing.getId().equals(id)) {
                throw new BusinessException("年级编码已存在");
            }
            grade.setCode(dto.getCode());
        }
        if (dto.getLevel() != null) {
            // 检查新级别是否已被其他年级使用
            Grade existing = this.getOne(new LambdaQueryWrapper<Grade>()
                    .eq(Grade::getTenantId, tenantId)
                    .eq(Grade::getLevel, dto.getLevel())
                    .eq(Grade::getDeleted, 0)
                    .ne(Grade::getId, id));
            if (existing != null) {
                throw new BusinessException("年级级别已存在");
            }
            grade.setLevel(dto.getLevel());
        }
        if (dto.getDescription() != null) {
            grade.setDescription(dto.getDescription());
        }

        this.updateById(grade);
        log.info("更新年级成功，ID={}", id);

        return convertToVO(grade);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long id, Long tenantId) {
        Grade grade = this.getById(id);
        if (grade == null || !grade.getTenantId().equals(tenantId)) {
            throw new BusinessException("年级不存在");
        }

        grade.setDeleted(1);
        this.updateById(grade);
        log.info("删除年级成功，ID={}", id);
    }

    private GradeVO convertToVO(Grade grade) {
        GradeVO vo = new GradeVO();
        vo.setId(grade.getId());
        vo.setTenantId(grade.getTenantId());
        vo.setName(grade.getName());
        vo.setCode(grade.getCode());
        vo.setLevel(grade.getLevel());
        vo.setDescription(grade.getDescription());
        vo.setValidState(grade.getValidState());
        vo.setCreateTime(grade.getCreateTime());
        vo.setUpdateTime(grade.getUpdateTime());
        return vo;
    }
}
