package com.pangu.student.listener;

import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.pangu.base.service.IRegionService;
import com.pangu.member.service.IMemberService;
import com.pangu.school.service.ISchoolService;
import com.pangu.student.domain.dto.StudentDTO;
import com.pangu.student.domain.dto.StudentImportDTO;
import com.pangu.student.domain.vo.ImportResultVO;
import com.pangu.student.service.IStudentService;
import lombok.extern.slf4j.Slf4j;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

/**
 * 学生导入监听器
 * 
 * @author pangu
 */
@Slf4j
public class StudentImportListener extends AnalysisEventListener<StudentImportDTO> {

    private final IStudentService studentService;
    private final IRegionService regionService;
    private final ISchoolService schoolService;
    private final IMemberService memberService;
    private final ImportResultVO result = new ImportResultVO();
    private int rowNum = 1; // 从第2行开始（第1行是表头）

    public StudentImportListener(IStudentService studentService, 
                                  IRegionService regionService,
                                  ISchoolService schoolService,
                                  IMemberService memberService) {
        this.studentService = studentService;
        this.regionService = regionService;
        this.schoolService = schoolService;
        this.memberService = memberService;
        result.setTotal(0);
        result.setSuccessCount(0);
        result.setFailCount(0);
    }

    @Override
    public void invoke(StudentImportDTO data, AnalysisContext context) {
        rowNum++;
        result.setTotal(result.getTotal() + 1);

        try {
            // 数据校验
            String errorMsg = validateData(data);
            if (StrUtil.isNotBlank(errorMsg)) {
                addError(rowNum, data, errorMsg);
                result.setFailCount(result.getFailCount() + 1);
                return;
            }

            // 1. 根据区域路径查询区域ID
            Long regionId = regionService.getRegionIdByPath(data.getRegionPath());
            if (regionId == null) {
                addError(rowNum, data, "区域不存在：" + data.getRegionPath());
                result.setFailCount(result.getFailCount() + 1);
                return;
            }

            // 2. 根据学校名称查询学校ID
            Long schoolId = schoolService.getSchoolIdByName(data.getSchoolName(), regionId);
            if (schoolId == null) {
                addError(rowNum, data, "学校不存在：" + data.getSchoolName());
                result.setFailCount(result.getFailCount() + 1);
                return;
            }

            // 3. 根据年级名称查询学校年级ID
            Long schoolGradeId = schoolService.getSchoolGradeId(schoolId, data.getGradeName());
            if (schoolGradeId == null) {
                addError(rowNum, data, "年级不存在：" + data.getGradeName());
                result.setFailCount(result.getFailCount() + 1);
                return;
            }

            // 4. 根据班级名称查询学校班级ID
            Long schoolClassId = schoolService.getSchoolClassId(schoolGradeId, data.getClassName());
            if (schoolClassId == null) {
                addError(rowNum, data, "班级不存在：" + data.getClassName());
                result.setFailCount(result.getFailCount() + 1);
                return;
            }

            // 5. 根据手机号查询或创建会员
            Long memberId = memberService.getOrCreateMemberByPhone(data.getMemberPhone());
            if (memberId == null) {
                addError(rowNum, data, "会员创建失败");
                result.setFailCount(result.getFailCount() + 1);
                return;
            }

            // 6. 保存学生信息
            StudentDTO studentDTO = new StudentDTO();
            studentDTO.setStudentName(data.getStudentName());
            studentDTO.setStudentNo(data.getStudentNo());
            studentDTO.setGender(parseGender(data.getGender()));
            studentDTO.setBirthday(parseBirthday(data.getBirthday()));
            studentDTO.setRegionId(regionId);
            studentDTO.setRegionPath(data.getRegionPath());
            studentDTO.setSchoolId(schoolId);
            studentDTO.setSchoolGradeId(schoolGradeId);
            studentDTO.setSchoolClassId(schoolClassId);
            studentDTO.setMemberId(memberId);

            studentService.insertStudent(studentDTO);
            result.setSuccessCount(result.getSuccessCount() + 1);
            log.info("导入学生成功：{}", data.getStudentName());

        } catch (Exception e) {
            log.error("导入学生失败：{}", data.getStudentName(), e);
            addError(rowNum, data, e.getMessage());
            result.setFailCount(result.getFailCount() + 1);
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        log.info("学生导入完成，总数：{}，成功：{}，失败：{}", 
            result.getTotal(), result.getSuccessCount(), result.getFailCount());
    }

    /**
     * 数据校验
     */
    private String validateData(StudentImportDTO data) {
        if (StrUtil.isBlank(data.getStudentName())) {
            return "学生姓名不能为空";
        }
        if (StrUtil.isBlank(data.getStudentNo())) {
            return "学号不能为空";
        }
        if (StrUtil.isBlank(data.getMemberPhone())) {
            return "用户手机号不能为空";
        }
        if (StrUtil.isBlank(data.getRegionPath())) {
            return "区域不能为空";
        }
        if (StrUtil.isBlank(data.getSchoolName())) {
            return "学校不能为空";
        }
        if (StrUtil.isBlank(data.getGradeName())) {
            return "年级不能为空";
        }
        if (StrUtil.isBlank(data.getClassName())) {
            return "班级不能为空";
        }
        return null;
    }

    /**
     * 添加错误信息
     */
    private void addError(int rowNum, StudentImportDTO data, String errorMsg) {
        ImportResultVO.ErrorItem error = new ImportResultVO.ErrorItem();
        error.setRowNum(rowNum);
        error.setStudentName(data.getStudentName());
        error.setStudentNo(data.getStudentNo());
        error.setErrorMsg(errorMsg);
        result.getErrorList().add(error);
    }

    public ImportResultVO getResult() {
        return result;
    }

    /**
     * 解析性别
     */
    private String parseGender(String gender) {
        if (StrUtil.isBlank(gender)) {
            return "0";
        }
        return switch (gender) {
            case "男" -> "1";
            case "女" -> "2";
            default -> "0";
        };
    }

    /**
     * 解析出生年月
     */
    private LocalDate parseBirthday(String birthday) {
        if (StrUtil.isBlank(birthday)) {
            return null;
        }
        try {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM");
            return LocalDate.parse(birthday + "-01", DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        } catch (Exception e) {
            log.warn("解析出生年月失败：{}", birthday);
            return null;
        }
    }
}
