package com.reading.platform.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.reading.platform.common.enums.ErrorCode;
import com.reading.platform.common.exception.BusinessException;
import com.reading.platform.common.util.PageUtils;
import com.reading.platform.dto.request.StudentCreateRequest;
import com.reading.platform.dto.request.StudentUpdateRequest;
import com.reading.platform.dto.response.StudentTransferHistoryResponse;
import com.reading.platform.entity.ParentStudent;
import com.reading.platform.entity.Student;
import com.reading.platform.entity.StudentClassHistory;
import com.reading.platform.entity.Clazz;
import com.reading.platform.mapper.ParentStudentMapper;
import com.reading.platform.mapper.StudentClassHistoryMapper;
import com.reading.platform.mapper.StudentMapper;
import com.reading.platform.mapper.ClazzMapper;
import com.reading.platform.service.StudentService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

@Service
@RequiredArgsConstructor
public class StudentServiceImpl implements StudentService {

    private final StudentMapper studentMapper;
    private final ParentStudentMapper parentStudentMapper;
    private final StudentClassHistoryMapper studentClassHistoryMapper;
    private final ClazzMapper classMapper;

    @Override
    @Transactional
    public Student createStudent(String tenantId, StudentCreateRequest request) {
        Student student = new Student();
        student.setTenantId(tenantId);
        student.setName(request.getName());
        student.setGender(request.getGender());
        student.setBirthDate(request.getBirthDate());
        student.setGrade(request.getGrade());
        student.setStudentNo(request.getStudentNo());
        student.setReadingLevel(request.getReadingLevel());
        student.setInterests(request.getInterests());
        student.setNotes(request.getNotes());
        student.setStatus("active");

        studentMapper.insert(student);
        return student;
    }

    @Override
    @Transactional
    public Student updateStudent(String id, StudentUpdateRequest request) {
        Student student = getStudentById(id);

        if (StringUtils.hasText(request.getName())) {
            student.setName(request.getName());
        }
        if (request.getGender() != null) {
            student.setGender(request.getGender());
        }
        if (request.getBirthDate() != null) {
            student.setBirthDate(request.getBirthDate());
        }
        if (request.getAvatarUrl() != null) {
            student.setAvatarUrl(request.getAvatarUrl());
        }
        if (request.getGrade() != null) {
            student.setGrade(request.getGrade());
        }
        if (request.getStudentNo() != null) {
            student.setStudentNo(request.getStudentNo());
        }
        if (request.getReadingLevel() != null) {
            student.setReadingLevel(request.getReadingLevel());
        }
        if (request.getInterests() != null) {
            student.setInterests(request.getInterests());
        }
        if (request.getNotes() != null) {
            student.setNotes(request.getNotes());
        }
        if (StringUtils.hasText(request.getStatus())) {
            student.setStatus(request.getStatus());
        }

        studentMapper.updateById(student);
        return student;
    }

    @Override
    public Student getStudentById(String id) {
        Student student = studentMapper.selectById(id);
        if (student == null) {
            throw new BusinessException(ErrorCode.DATA_NOT_FOUND, "Student not found");
        }
        return student;
    }

    @Override
    public Page<Student> getStudentPage(String tenantId, Integer pageNum, Integer pageSize, String keyword, String grade, String status) {
        Page<Student> page = PageUtils.of(pageNum, pageSize);
        LambdaQueryWrapper<Student> wrapper = new LambdaQueryWrapper<>();

        wrapper.eq(Student::getTenantId, tenantId);

        if (StringUtils.hasText(keyword)) {
            wrapper.and(w -> w
                    .like(Student::getName, keyword)
                    .or()
                    .like(Student::getStudentNo, keyword)
            );
        }
        if (StringUtils.hasText(grade)) {
            wrapper.eq(Student::getGrade, grade);
        }
        if (StringUtils.hasText(status)) {
            wrapper.eq(Student::getStatus, status);
        }
        wrapper.orderByDesc(Student::getCreatedAt);

        return studentMapper.selectPage(page, wrapper);
    }

    @Override
    public Page<Student> getStudentsByClassId(String classId, Integer pageNum, Integer pageSize) {
        Page<Student> page = PageUtils.of(pageNum, pageSize);

        // Get active student IDs from class history
        List<StudentClassHistory> histories = studentClassHistoryMapper.selectList(
                new LambdaQueryWrapper<StudentClassHistory>()
                        .eq(StudentClassHistory::getClassId, classId)
                        .eq(StudentClassHistory::getStatus, "active")
                        .isNull(StudentClassHistory::getEndDate)
                        .or()
                        .ge(StudentClassHistory::getEndDate, LocalDate.now())
        );

        if (histories.isEmpty()) {
            return page;
        }

        List<String> studentIds = histories.stream()
                .map(StudentClassHistory::getStudentId)
                .toList();

        if (studentIds.isEmpty()) {
            return page;
        }

        LambdaQueryWrapper<Student> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(Student::getId, studentIds)
                .eq(Student::getStatus, "active")
                .orderByAsc(Student::getName);

        return studentMapper.selectPage(page, wrapper);
    }

    @Override
    @Transactional
    public void deleteStudent(String id) {
        getStudentById(id);
        studentMapper.deleteById(id);
    }

    @Override
    public List<Student> getStudentsByParentId(String parentId) {
        List<ParentStudent> parentStudents = parentStudentMapper.selectList(
                new LambdaQueryWrapper<ParentStudent>()
                        .eq(ParentStudent::getParentId, parentId)
        );

        if (parentStudents.isEmpty()) {
            return new ArrayList<>();
        }

        List<String> studentIds = parentStudents.stream()
                .map(ParentStudent::getStudentId)
                .toList();

        return studentMapper.selectList(
                new LambdaQueryWrapper<Student>()
                        .in(Student::getId, studentIds)
                        .eq(Student::getStatus, "active")
        );
    }

    @Override
    @Transactional
    public List<Student> importStudents(String tenantId, List<StudentCreateRequest> requests) {
        List<Student> students = new ArrayList<>();
        for (StudentCreateRequest request : requests) {
            Student student = createStudent(tenantId, request);
            students.add(student);
        }
        return students;
    }

    @Override
    @Transactional
    public void transferStudent(String tenantId, String studentId, String toClassId, String reason) {
        // 验证学生存在
        Student student = getStudentById(studentId);
        if (!student.getTenantId().equals(tenantId)) {
            throw new BusinessException(ErrorCode.DATA_NOT_FOUND, "学生不存在或无权限访问");
        }

        // 结束当前班级关系
        List<StudentClassHistory> currentHistories = studentClassHistoryMapper.selectList(
                new LambdaQueryWrapper<StudentClassHistory>()
                        .eq(StudentClassHistory::getStudentId, studentId)
                        .eq(StudentClassHistory::getStatus, "active")
                        .isNull(StudentClassHistory::getEndDate)
        );

        for (StudentClassHistory history : currentHistories) {
            history.setEndDate(LocalDate.now());
            history.setStatus("left");
            studentClassHistoryMapper.updateById(history);
        }

        // 创建新的班级关系
        StudentClassHistory newHistory = new StudentClassHistory();
        newHistory.setStudentId(studentId);
        newHistory.setClassId(toClassId);
        newHistory.setStartDate(LocalDate.now());
        newHistory.setStatus("active");
        newHistory.setReason(reason);
        studentClassHistoryMapper.insert(newHistory);
    }

    @Override
    public List<StudentTransferHistoryResponse> getStudentClassHistory(String studentId) {
        List<StudentClassHistory> histories = studentClassHistoryMapper.selectList(
                new LambdaQueryWrapper<StudentClassHistory>()
                        .eq(StudentClassHistory::getStudentId, studentId)
                        .orderByDesc(StudentClassHistory::getStartDate)
        );

        List<StudentTransferHistoryResponse> result = new ArrayList<>();
        for (StudentClassHistory history : histories) {
            StudentTransferHistoryResponse response = new StudentTransferHistoryResponse();
            response.setId(history.getId());
            response.setClassId(history.getClassId());
            response.setStartDate(history.getStartDate() != null ? history.getStartDate().toString() : null);
            response.setEndDate(history.getEndDate() != null ? history.getEndDate().toString() : null);
            response.setStatus(history.getStatus());
            response.setReason(history.getReason());

            // 获取班级名称
            if (history.getClassId() != null) {
                var clazz = classMapper.selectById(history.getClassId());
                if (clazz != null) {
                    response.setClassName(clazz.getName());
                }
            }

            result.add(response);
        }

        return result;
    }

}
