package top.awinx.stu01.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import top.awinx.stu01.dto.TeacherAddDTO;
import top.awinx.stu01.dto.TeacherUpdateDTO;
import top.awinx.stu01.entity.Course;
import top.awinx.stu01.entity.SysUser;
import top.awinx.stu01.entity.Teacher;
import top.awinx.stu01.exception.BusinessException;
import top.awinx.stu01.mapper.CourseMapper;
import top.awinx.stu01.mapper.SysUserMapper;
import top.awinx.stu01.mapper.TeacherMapper;
import top.awinx.stu01.service.TeacherService;

import java.time.LocalDateTime;

/**
 * 教师Service实现类（新增删除关联拦截逻辑）
 */
@Service
public class TeacherServiceImpl extends ServiceImpl<TeacherMapper, Teacher> implements TeacherService {

    @Resource
    private SysUserMapper sysUserMapper;
    // 新增：注入CourseMapper用于关联校验
    @Resource
    private CourseMapper courseMapper;

    @Override
    public Teacher addTeacher(TeacherAddDTO addDTO) {
        // 1. 基础参数非空+格式校验
        if (addDTO.getTeaNo() == null || !addDTO.getTeaNo().matches("^\\d{8}$")) {
            throw new BusinessException("教师编号必须为8位纯数字");
        }
        if (addDTO.getName() == null || addDTO.getName().trim().isEmpty()) {
            throw new BusinessException("教师姓名不能为空");
        }
        if (addDTO.getUserId() == null || addDTO.getUserId() < 0) {
            throw new BusinessException("关联用户ID不能为空且为非负整数");
        }

        // 2. 教师编号唯一性校验
        LambdaQueryWrapper<Teacher> teaWrapper = new LambdaQueryWrapper<>();
        teaWrapper.eq(Teacher::getTeaNo, addDTO.getTeaNo());
        if (this.count(teaWrapper) > 0) {
            throw new BusinessException("教师编号" + addDTO.getTeaNo() + "已存在");
        }

        // 3. 关联用户ID存在性校验（外键约束前置校验）
        SysUser sysUser = sysUserMapper.selectById(addDTO.getUserId());
        if (sysUser == null) {
            throw new BusinessException("关联的用户ID" + addDTO.getUserId() + "不存在（sys_user表无此记录）");
        }
        // 额外校验：关联用户类型必须是教师（user_type=2）
        if (sysUser.getUserType() != 2) {
            throw new BusinessException("关联的用户ID" + addDTO.getUserId() + "不是教师类型（user_type必须为2）");
        }

        // 4. DTO转实体（createTime由数据库默认值填充，也可手动设置）
        Teacher teacher = new Teacher();
        teacher.setTeaNo(addDTO.getTeaNo());
        teacher.setName(addDTO.getName());
        teacher.setUserId(addDTO.getUserId());
        teacher.setCreateTime(LocalDateTime.now()); // 与数据库CURRENT_TIMESTAMP保持一致

        this.save(teacher);
        return teacher;
    }

    @Override
    public boolean updateTeacher(TeacherUpdateDTO updateDTO) {
        // 1. 校验教师ID存在性
        if (updateDTO.getId() == null || !this.existsById(updateDTO.getId())) {
            throw new BusinessException("教师ID不存在，更新失败");
        }

        // 2. 校验更新的姓名非空
        if (updateDTO.getName() != null && updateDTO.getName().trim().isEmpty()) {
            throw new BusinessException("教师姓名不能为空");
        }

        // 3. 构建更新实体（仅更新姓名）
        Teacher teacher = new Teacher();
        teacher.setId(updateDTO.getId());
        if (updateDTO.getName() != null) {
            teacher.setName(updateDTO.getName());
        }

        return this.updateById(teacher);
    }

    @Override
    public boolean deleteTeacher(Long id) {
        // 1. 基础校验：教师ID存在性
        if (id == null || !this.existsById(id)) {
            throw new BusinessException("教师ID不存在，删除失败");
        }

        // 2. 新增：关联课程校验（核心拦截逻辑）
        LambdaQueryWrapper<Course> courseWrapper = new LambdaQueryWrapper<>();
        courseWrapper.eq(Course::getTeaId, id); // 匹配course表中关联的教师ID
        long relatedCourseCount = courseMapper.selectCount(courseWrapper);
        if (relatedCourseCount > 0) {
            throw new BusinessException("教师ID" + id + "关联了" + relatedCourseCount + "门课程，禁止删除");
        }

        // 3. 无关联课程时执行物理删除
        return this.removeById(id);
    }

    private boolean existsById(Long id) {
        return this.count(new LambdaQueryWrapper<Teacher>().eq(Teacher::getId, id)) > 0;
    }
}
