package com.pangu.school.service;

import com.pangu.common.core.exception.ServiceException;
import com.pangu.school.domain.dto.SchoolCreateDTO;
import com.pangu.school.domain.dto.SchoolQueryDTO;
import com.pangu.school.domain.entity.School;
import com.pangu.school.domain.vo.SchoolTreeVO;
import com.pangu.school.domain.vo.SchoolVO;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;

import static org.junit.jupiter.api.Assertions.*;

/**
 * 学校服务测试类
 * @author pangu
 */
@SpringBootTest
@Transactional // 测试完成后回滚
public class SchoolServiceTest {

    @Autowired
    private ISchoolService schoolService;

    /**
     * 测试新增学校
     */
    @Test
    public void testInsertSchool() {
        SchoolCreateDTO dto = new SchoolCreateDTO();
        dto.setSchoolName("测试学校");
        dto.setSchoolType("02");
        dto.setRegionId(111L);
        dto.setStatus("0");

        int result = schoolService.insertSchool(dto);

        assertEquals(1, result);
    }

    /**
     * 测试查询学校列表
     */
    @Test
    public void testSelectSchoolList() {
        SchoolQueryDTO query = new SchoolQueryDTO();
        query.setRegionId(111L);

        List<SchoolVO> list = schoolService.selectSchoolList(query);

        assertNotNull(list);
        assertTrue(list.size() > 0);
    }

    /**
     * 测试查询学校树
     */
    @Test
    public void testSelectSchoolTree() {
        List<SchoolTreeVO> tree = schoolService.selectSchoolTree(111L);

        assertNotNull(tree);
        assertTrue(tree.size() > 0);

        // 验证树形结构
        SchoolTreeVO school = tree.get(0);
        assertEquals("school", school.getType());
        assertNotNull(school.getCode());
    }

    /**
     * 测试根据ID查询学校
     */
    @Test
    public void testSelectSchoolById() {
        SchoolVO school = schoolService.selectSchoolById(1L);

        assertNotNull(school);
        assertEquals(1L, school.getSchoolId());
    }

    /**
     * 测试修改学校
     */
    @Test
    public void testUpdateSchool() {
        School school = new School();
        school.setSchoolId(1L);
        school.setSchoolName("武汉市第一中学（更新）");

        int result = schoolService.updateSchool(school);

        assertEquals(1, result);
    }

    /**
     * 测试删除有子级的学校（应该失败）
     */
    @Test
    public void testDeleteSchoolWithGrades() {
        // 学校ID=1有年级数据，删除应抛出异常
        assertThrows(ServiceException.class, () -> {
            schoolService.deleteSchool(1L);
        });
    }

    /**
     * 测试挂载年级
     */
    @Test
    public void testBindGrades() {
        Long schoolId = 2L; // 使用没有年级的学校
        List<Long> gradeIds = Arrays.asList(1L, 2L, 3L);

        int result = schoolService.bindGrades(schoolId, gradeIds);

        assertTrue(result > 0);
    }

    /**
     * 测试重复挂载年级（应该忽略重复）
     */
    @Test
    public void testBindGradesDuplicate() {
        Long schoolId = 1L; // 已有年级7、8、9
        List<Long> gradeIds = Arrays.asList(7L, 10L, 11L); // 7重复，10、11新增

        int result = schoolService.bindGrades(schoolId, gradeIds);

        // 应该只插入2条（10、11）
        assertEquals(2, result);
    }

    /**
     * 测试挂载班级
     */
    @Test
    public void testBindClasses() {
        Long schoolGradeId = 2L; // 学校ID=1的八年级
        List<Long> classIds = Arrays.asList(1L, 2L, 3L);

        int result = schoolService.bindClasses(schoolGradeId, classIds);

        assertTrue(result > 0);
    }

    /**
     * 测试删除有班级的年级（应该失败）
     */
    @Test
    public void testDeleteSchoolGradeWithClasses() {
        // 学校年级ID=1有班级数据，删除应抛出异常
        assertThrows(ServiceException.class, () -> {
            schoolService.deleteSchoolGrade(1L);
        });
    }

    /**
     * 测试学校编码生成
     */
    @Test
    public void testSchoolCodeGeneration() {
        SchoolCreateDTO dto1 = new SchoolCreateDTO();
        dto1.setSchoolName("测试学校1");
        dto1.setSchoolType("01");
        dto1.setRegionId(111L);
        dto1.setStatus("0");

        SchoolCreateDTO dto2 = new SchoolCreateDTO();
        dto2.setSchoolName("测试学校2");
        dto2.setSchoolType("01");
        dto2.setRegionId(111L);
        dto2.setStatus("0");

        schoolService.insertSchool(dto1);
        schoolService.insertSchool(dto2);

        // 验证编码格式：SCH + 年份 + 4位序号
        SchoolQueryDTO query = new SchoolQueryDTO();
        query.setSchoolName("测试学校");
        List<SchoolVO> list = schoolService.selectSchoolList(query);

        assertTrue(list.size() >= 2);
        for (SchoolVO school : list) {
            assertTrue(school.getSchoolCode().matches("SCH\\d{8}"));
        }
    }
}
