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.schoolclass.CreateClassDTO;
import com.lesingle.creation.dto.schoolclass.UpdateClassDTO;
import com.lesingle.creation.entity.Grade;
import com.lesingle.creation.entity.SchoolClass;
import com.lesingle.creation.common.exception.BusinessException;
import com.lesingle.creation.mapper.GradeMapper;
import com.lesingle.creation.mapper.SchoolClassMapper;
import com.lesingle.creation.service.SchoolClassService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lesingle.creation.vo.grade.GradeVO;
import com.lesingle.creation.vo.schoolclass.ClassVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 班级服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SchoolClassServiceImpl extends ServiceImpl<SchoolClassMapper, SchoolClass> implements SchoolClassService {

    private final SchoolClassMapper schoolClassMapper;
    private final GradeMapper gradeMapper;

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

        // 验证年级是否存在
        Grade grade = gradeMapper.selectById(dto.getGradeId());
        if (grade == null) {
            throw new BusinessException("年级不存在");
        }

        SchoolClass schoolClass = new SchoolClass();
        schoolClass.setTenantId(tenantId);
        schoolClass.setGradeId(dto.getGradeId());
        schoolClass.setName(dto.getName());
        schoolClass.setCode(dto.getCode());
        schoolClass.setType(dto.getType());
        schoolClass.setCapacity(dto.getCapacity());
        schoolClass.setDescription(dto.getDescription());
        schoolClass.setValidState(1);

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

        return convertToVO(schoolClass);
    }

    @Override
    public Page<ClassVO> pageQuery(Integer pageNum, Integer pageSize, Long tenantId, Long gradeId, Integer type) {
        Page<SchoolClass> page = new Page<>(pageNum, pageSize);

        LambdaQueryWrapper<SchoolClass> wrapper = new LambdaQueryWrapper<SchoolClass>()
                .eq(SchoolClass::getTenantId, tenantId)
                .eq(SchoolClass::getDeleted, 0)
                .eq(gradeId != null, SchoolClass::getGradeId, gradeId)
                .eq(type != null, SchoolClass::getType, type)
                .orderByAsc(SchoolClass::getName);

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

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

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

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ClassVO update(Long id, UpdateClassDTO dto, Long tenantId, Long modifierId) {
        SchoolClass schoolClass = this.getById(id);
        if (schoolClass == null || !schoolClass.getTenantId().equals(tenantId)) {
            throw new BusinessException("班级不存在");
        }

        if (dto.getGradeId() != null) {
            // 验证年级是否存在
            Grade grade = gradeMapper.selectById(dto.getGradeId());
            if (grade == null) {
                throw new BusinessException("年级不存在");
            }
            schoolClass.setGradeId(dto.getGradeId());
        }
        if (dto.getName() != null) {
            schoolClass.setName(dto.getName());
        }
        if (dto.getCode() != null) {
            // 检查新编码是否已被其他班级使用
            SchoolClass existing = schoolClassMapper.selectByCode(tenantId, dto.getCode());
            if (existing != null && !existing.getId().equals(id)) {
                throw new BusinessException("班级编码已存在");
            }
            schoolClass.setCode(dto.getCode());
        }
        if (dto.getType() != null) {
            schoolClass.setType(dto.getType());
        }
        if (dto.getCapacity() != null) {
            schoolClass.setCapacity(dto.getCapacity());
        }
        if (dto.getDescription() != null) {
            schoolClass.setDescription(dto.getDescription());
        }

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

        return convertToVO(schoolClass);
    }

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

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

    private ClassVO convertToVO(SchoolClass schoolClass) {
        ClassVO vo = new ClassVO();
        vo.setId(schoolClass.getId());
        vo.setTenantId(schoolClass.getTenantId());
        vo.setGradeId(schoolClass.getGradeId());
        vo.setName(schoolClass.getName());
        vo.setCode(schoolClass.getCode());
        vo.setType(schoolClass.getType());
        vo.setCapacity(schoolClass.getCapacity());
        vo.setDescription(schoolClass.getDescription());
        vo.setValidState(schoolClass.getValidState());
        vo.setCreateTime(schoolClass.getCreateTime());
        vo.setUpdateTime(schoolClass.getUpdateTime());

        // 关联查询年级信息
        Grade grade = gradeMapper.selectById(schoolClass.getGradeId());
        if (grade != null) {
            GradeVO gradeVO = new GradeVO();
            gradeVO.setId(grade.getId());
            gradeVO.setName(grade.getName());
            gradeVO.setCode(grade.getCode());
            gradeVO.setLevel(grade.getLevel());
            vo.setGrade(gradeVO);
        }

        return vo;
    }
}
