package com.pangu.student.service;

import com.pangu.common.core.exception.ServiceException;
import com.pangu.common.core.page.TableDataInfo;
import com.pangu.student.domain.dto.StudentDTO;
import com.pangu.student.domain.entity.Student;
import com.pangu.student.domain.vo.StudentVO;
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.time.LocalDate;

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

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

    @Autowired
    private IStudentService studentService;

    @Test
    public void testInsertStudent() {
        StudentDTO dto = new StudentDTO();
        dto.setStudentName("测试学生");
        dto.setStudentNo("TEST001");
        dto.setGender("1");
        dto.setBirthday(LocalDate.of(2015, 3, 15));
        dto.setRegionId(111L);
        dto.setRegionPath("湖北省-武汉市-武昌区");
        dto.setSchoolId(1L);
        dto.setSchoolGradeId(1L);
        dto.setSchoolClassId(1L);
        dto.setMemberId(1L);

        int result = studentService.insertStudent(dto);
        assertEquals(1, result);
    }

    @Test
    public void testInsertStudentWithDuplicateNo() {
        StudentDTO dto = new StudentDTO();
        dto.setStudentName("测试学生");
        dto.setStudentNo("STU20260001"); // 已存在的学号
        dto.setGender("1");
        dto.setRegionId(111L);
        dto.setSchoolId(1L);
        dto.setSchoolGradeId(1L);
        dto.setSchoolClassId(1L);
        dto.setMemberId(1L);

        assertThrows(ServiceException.class, () -> {
            studentService.insertStudent(dto);
        });
    }

    @Test
    public void testSelectStudentList() {
        StudentDTO dto = new StudentDTO();
        dto.setPageNum(1);
        dto.setPageSize(10);

        TableDataInfo result = studentService.selectStudentList(dto);
        assertNotNull(result);
        assertTrue(result.getTotal() > 0);
    }

    @Test
    public void testGetStudentById() {
        StudentVO vo = studentService.getStudentById(1L);
        assertNotNull(vo);
        assertEquals("张小明", vo.getStudentName());
    }

    @Test
    public void testUpdateStudent() {
        StudentDTO dto = new StudentDTO();
        dto.setStudentId(1L);
        dto.setStudentName("张小明（更新）");
        dto.setStudentNo("STU20260001");
        dto.setGender("1");
        dto.setRegionId(111L);
        dto.setSchoolId(1L);
        dto.setSchoolGradeId(1L);
        dto.setSchoolClassId(1L);
        dto.setMemberId(1L);

        int result = studentService.updateStudent(dto);
        assertEquals(1, result);
    }

    @Test
    public void testDeleteStudent() {
        int result = studentService.deleteStudent(1L);
        assertEquals(1, result);
    }

    @Test
    public void testCheckStudentNoUnique() {
        boolean unique = studentService.checkStudentNoUnique("STU20260001", null);
        assertFalse(unique); // 已存在

        unique = studentService.checkStudentNoUnique("STU99999", null);
        assertTrue(unique); // 不存在
    }

    /**
     * 测试检查学生是否在指定学校
     */
    @Test
    public void testIsStudentInSchool() {
        // 学生ID=1应该在学校ID=1
        boolean inSchool = studentService.isStudentInSchool(1L, 1L);
        assertTrue(inSchool);

        // 学生ID=1不在学校ID=999
        boolean notInSchool = studentService.isStudentInSchool(1L, 999L);
        assertFalse(notInSchool);
    }

    /**
     * 测试更新学生会员关联
     */
    @Test
    public void testUpdateStudentMember() {
        // 先新增一个学生
        StudentDTO dto = new StudentDTO();
        dto.setStudentName("会员测试学生");
        dto.setStudentNo("MEMBER_TEST_001");
        dto.setGender("1");
        dto.setRegionId(111L);
        dto.setSchoolId(1L);
        dto.setSchoolGradeId(1L);
        dto.setSchoolClassId(1L);
        studentService.insertStudent(dto);

        // 查询该学生
        StudentDTO query = new StudentDTO();
        query.setStudentNo("MEMBER_TEST_001");
        query.setPageNum(1);
        query.setPageSize(10);
        TableDataInfo result = studentService.selectStudentList(query);
        assertTrue(result.getTotal() > 0);

        // 获取学生ID并绑定会员
        @SuppressWarnings("unchecked")
        java.util.List<StudentVO> list = (java.util.List<StudentVO>) result.getRows();
        Long studentId = list.get(0).getStudentId();

        int updateResult = studentService.updateStudentMember(studentId, 1L);
        assertEquals(1, updateResult);
    }

    /**
     * 测试解绑学生
     */
    @Test
    public void testUnbindStudent() {
        // 先新增一个绑定了会员的学生
        StudentDTO dto = new StudentDTO();
        dto.setStudentName("解绑测试学生");
        dto.setStudentNo("UNBIND_TEST_001");
        dto.setGender("1");
        dto.setRegionId(111L);
        dto.setSchoolId(1L);
        dto.setSchoolGradeId(1L);
        dto.setSchoolClassId(1L);
        dto.setMemberId(1L);
        studentService.insertStudent(dto);

        // 查询学生获取ID
        StudentDTO query = new StudentDTO();
        query.setStudentNo("UNBIND_TEST_001");
        query.setPageNum(1);
        query.setPageSize(10);
        TableDataInfo result = studentService.selectStudentList(query);
        @SuppressWarnings("unchecked")
        java.util.List<StudentVO> list = (java.util.List<StudentVO>) result.getRows();
        Long studentId = list.get(0).getStudentId();

        // 解绑
        int unbindResult = studentService.unbindStudent(studentId);
        assertEquals(1, unbindResult);
    }

    /**
     * 测试统计会员绑定的学生数量
     */
    @Test
    public void testCountByMemberId() {
        // 测试数据中会员ID=1应该有绑定学生
        int count = studentService.countByMemberId(1L);
        assertTrue(count >= 0);
    }

    /**
     * 测试查询会员绑定的学生列表
     */
    @Test
    public void testSelectStudentVOsByMemberId() {
        java.util.List<StudentVO> students = studentService.selectStudentVOsByMemberId(1L);
        assertNotNull(students);
    }

    /**
     * 测试统计学校学生数量
     */
    @Test
    public void testCountBySchoolId() {
        int count = studentService.countBySchoolId(1L);
        assertTrue(count >= 0);
    }

    /**
     * 测试统计年级学生数量
     */
    @Test
    public void testCountBySchoolGradeId() {
        int count = studentService.countBySchoolGradeId(1L);
        assertTrue(count >= 0);
    }

    /**
     * 测试统计班级学生数量
     */
    @Test
    public void testCountBySchoolClassId() {
        int count = studentService.countBySchoolClassId(1L);
        assertTrue(count >= 0);
    }

    /**
     * 测试绑定会员方法
     */
    @Test
    public void testBindMember() {
        // 先新增一个学生
        StudentDTO dto = new StudentDTO();
        dto.setStudentName("绑定会员测试");
        dto.setStudentNo("BIND_MEMBER_001");
        dto.setGender("1");
        dto.setRegionId(111L);
        dto.setSchoolId(1L);
        dto.setSchoolGradeId(1L);
        dto.setSchoolClassId(1L);
        studentService.insertStudent(dto);

        // 查询学生获取ID
        StudentDTO query = new StudentDTO();
        query.setStudentNo("BIND_MEMBER_001");
        query.setPageNum(1);
        query.setPageSize(10);
        TableDataInfo result = studentService.selectStudentList(query);
        @SuppressWarnings("unchecked")
        java.util.List<StudentVO> list = (java.util.List<StudentVO>) result.getRows();
        Long studentId = list.get(0).getStudentId();

        // 绑定会员
        assertDoesNotThrow(() -> {
            studentService.bindMember(studentId, 1L);
        });
    }
}
