package com.pangu.student.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
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.dto.StudentImportDTO;
import com.pangu.student.domain.entity.Student;
import com.pangu.student.domain.vo.ImportResultVO;
import com.pangu.student.domain.vo.StudentVO;
import com.pangu.student.listener.StudentImportListener;
import com.pangu.student.mapper.StudentMapper;
import com.pangu.student.service.IStudentService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;

/**
 * 学生服务实现
 * 
 * @author pangu
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements IStudentService {

    private final StudentMapper studentMapper;
    private final com.pangu.base.service.IRegionService regionService;
    private final com.pangu.school.service.ISchoolService schoolService;
    private final com.pangu.member.service.IMemberService memberService;

    @Override
    public TableDataInfo selectStudentList(StudentDTO studentDTO) {
        Page<StudentVO> page = new Page<>(
            studentDTO.getPageNum() != null ? studentDTO.getPageNum() : 1,
            studentDTO.getPageSize() != null ? studentDTO.getPageSize() : 10
        );
        List<StudentVO> list = studentMapper.selectStudentVOList(page, studentDTO);
        return new TableDataInfo(list, page.getTotal());
    }

    @Override
    public StudentVO getStudentById(Long studentId) {
        return studentMapper.selectStudentVOById(studentId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertStudent(StudentDTO studentDTO) {
        // 校验学号唯一性
        if (StrUtil.isNotBlank(studentDTO.getStudentNo())) {
            if (!checkStudentNoUnique(studentDTO.getStudentNo(), null)) {
                throw new ServiceException("学号已存在");
            }
        }

        Student student = buildStudent(studentDTO);
        student.setStatus("0");
        int result = studentMapper.insert(student);
        log.info("新增学生成功, studentId={}, studentName={}", student.getStudentId(), student.getStudentName());
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateStudent(StudentDTO studentDTO) {
        // 校验学号唯一性
        if (StrUtil.isNotBlank(studentDTO.getStudentNo())) {
            if (!checkStudentNoUnique(studentDTO.getStudentNo(), studentDTO.getStudentId())) {
                throw new ServiceException("学号已存在");
            }
        }

        Student student = buildStudent(studentDTO);
        student.setStudentId(studentDTO.getStudentId());
        int result = studentMapper.updateById(student);
        log.info("修改学生成功, studentId={}, studentName={}", student.getStudentId(), student.getStudentName());
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteStudent(Long studentId) {
        Student student = new Student();
        student.setStudentId(studentId);
        student.setDelFlag("1");
        int result = studentMapper.updateById(student);
        log.info("删除学生成功, studentId={}", studentId);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ImportResultVO importStudents(MultipartFile file) {
        try {
            StudentImportListener listener = new StudentImportListener(this, regionService, schoolService, memberService);
            EasyExcel.read(file.getInputStream(), StudentImportDTO.class, listener).sheet().doRead();
            return listener.getResult();
        } catch (IOException e) {
            log.error("导入学生失败", e);
            throw new ServiceException("导入失败：" + e.getMessage());
        }
    }

    @Override
    public boolean checkStudentNoUnique(String studentNo, Long studentId) {
        int count = studentMapper.countByStudentNo(studentNo, studentId);
        return count == 0;
    }

    @Override
    public boolean isStudentInSchool(Long studentId, Long schoolId) {
        Student student = studentMapper.selectById(studentId);
        if (student == null || "1".equals(student.getDelFlag())) {
            return false;
        }
        return student.getSchoolId().equals(schoolId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateStudentMember(Long studentId, Long memberId) {
        Student student = new Student();
        student.setStudentId(studentId);
        student.setMemberId(memberId);
        int result = studentMapper.updateById(student);
        log.info("更新学生会员关联成功, studentId={}, memberId={}", studentId, memberId);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int unbindStudent(Long studentId) {
        Student student = new Student();
        student.setStudentId(studentId);
        student.setMemberId(null);
        int result = studentMapper.updateById(student);
        log.info("解绑学生成功, studentId={}", studentId);
        return result;
    }

    @Override
    public int countByMemberId(Long memberId) {
        return studentMapper.countByMemberId(memberId);
    }

    @Override
    public List<StudentVO> selectStudentVOsByMemberId(Long memberId) {
        return studentMapper.selectStudentVOsByMemberId(memberId);
    }
    
    @Override
    public void bindMember(Long studentId, Long memberId) {
        if (studentId == null || memberId == null) {
            throw new ServiceException("学生ID和会员ID不能为空");
        }
        updateStudentMember(studentId, memberId);
    }

    /**
     * 构建学生对象
     */
    private Student buildStudent(StudentDTO dto) {
        Student student = new Student();
        student.setStudentName(dto.getStudentName());
        student.setStudentNo(dto.getStudentNo());
        student.setGender(dto.getGender());
        student.setBirthday(dto.getBirthday());
        student.setRegionId(dto.getRegionId());
        student.setRegionPath(dto.getRegionPath());
        student.setSchoolId(dto.getSchoolId());
        student.setSchoolGradeId(dto.getSchoolGradeId());
        student.setSchoolClassId(dto.getSchoolClassId());
        student.setSubjectId(dto.getSubjectId());
        student.setMemberId(dto.getMemberId());
        student.setRemark(dto.getRemark());
        return student;
    }
}
