package com.reading.platform.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
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.LessonCreateRequest;
import com.reading.platform.dto.request.LessonUpdateRequest;
import com.reading.platform.entity.Lesson;
import com.reading.platform.entity.LessonFeedback;
import com.reading.platform.entity.StudentRecord;
import com.reading.platform.mapper.LessonFeedbackMapper;
import com.reading.platform.mapper.LessonMapper;
import com.reading.platform.mapper.StudentRecordMapper;
import com.reading.platform.service.LessonService;
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.*;

@Service
@RequiredArgsConstructor
public class LessonServiceImpl extends ServiceImpl<LessonMapper, Lesson> implements LessonService {

    private final LessonMapper lessonMapper;
    private final StudentRecordMapper studentRecordMapper;
    private final LessonFeedbackMapper lessonFeedbackMapper;

    @Override
    @Transactional
    public Lesson createLesson(String tenantId, LessonCreateRequest request) {
        Lesson lesson = new Lesson();
        lesson.setTenantId(tenantId);
        lesson.setCourseId(request.getCourseId());
        lesson.setClassId(request.getClassId());
        lesson.setTeacherId(request.getTeacherId());
        lesson.setTitle(request.getTitle());
        lesson.setLessonDate(request.getLessonDate());
        lesson.setStartTime(request.getStartTime());
        lesson.setEndTime(request.getEndTime());
        lesson.setLocation(request.getLocation());
        lesson.setNotes(request.getNotes());
        lesson.setStatus("scheduled");

        lessonMapper.insert(lesson);
        return lesson;
    }

    @Override
    @Transactional
    public Lesson updateLesson(String id, LessonUpdateRequest request) {
        Lesson lesson = getLessonById(id);

        if (StringUtils.hasText(request.getTitle())) {
            lesson.setTitle(request.getTitle());
        }
        if (request.getLessonDate() != null) {
            lesson.setLessonDate(request.getLessonDate());
        }
        if (request.getStartTime() != null) {
            lesson.setStartTime(request.getStartTime());
        }
        if (request.getEndTime() != null) {
            lesson.setEndTime(request.getEndTime());
        }
        if (request.getLocation() != null) {
            lesson.setLocation(request.getLocation());
        }
        if (StringUtils.hasText(request.getStatus())) {
            lesson.setStatus(request.getStatus());
        }
        if (request.getNotes() != null) {
            lesson.setNotes(request.getNotes());
        }

        lessonMapper.updateById(lesson);
        return lesson;
    }

    @Override
    public Lesson getLessonById(String id) {
        Lesson lesson = lessonMapper.selectById(id);
        if (lesson == null) {
            throw new BusinessException(ErrorCode.DATA_NOT_FOUND, "Lesson not found");
        }
        return lesson;
    }

    @Override
    public Page<Lesson> getLessonPage(String tenantId, Integer pageNum, Integer pageSize, String classId, String teacherId, String status, LocalDate startDate, LocalDate endDate) {
        Page<Lesson> page = PageUtils.of(pageNum, pageSize);
        LambdaQueryWrapper<Lesson> wrapper = new LambdaQueryWrapper<>();

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

        if (classId != null) {
            wrapper.eq(Lesson::getClassId, classId);
        }
        if (teacherId != null) {
            wrapper.eq(Lesson::getTeacherId, teacherId);
        }
        if (StringUtils.hasText(status)) {
            wrapper.eq(Lesson::getStatus, status);
        }
        if (startDate != null) {
            wrapper.ge(Lesson::getLessonDate, startDate);
        }
        if (endDate != null) {
            wrapper.le(Lesson::getLessonDate, endDate);
        }
        wrapper.orderByAsc(Lesson::getLessonDate, Lesson::getStartTime);

        return lessonMapper.selectPage(page, wrapper);
    }

    @Override
    public Page<Lesson> getTeacherLessons(String teacherId, Integer pageNum, Integer pageSize, String status, LocalDate startDate, LocalDate endDate) {
        Page<Lesson> page = PageUtils.of(pageNum, pageSize);
        LambdaQueryWrapper<Lesson> wrapper = new LambdaQueryWrapper<>();

        wrapper.eq(Lesson::getTeacherId, teacherId);

        if (StringUtils.hasText(status)) {
            wrapper.eq(Lesson::getStatus, status);
        }
        if (startDate != null) {
            wrapper.ge(Lesson::getLessonDate, startDate);
        }
        if (endDate != null) {
            wrapper.le(Lesson::getLessonDate, endDate);
        }
        wrapper.orderByAsc(Lesson::getLessonDate, Lesson::getStartTime);

        return lessonMapper.selectPage(page, wrapper);
    }

    @Override
    @Transactional
    public void deleteLesson(String id) {
        getLessonById(id);
        lessonMapper.deleteById(id);
    }

    @Override
    @Transactional
    public void startLesson(String id) {
        Lesson lesson = getLessonById(id);
        lesson.setStatus("in_progress");
        lessonMapper.updateById(lesson);
    }

    @Override
    @Transactional
    public void completeLesson(String id) {
        Lesson lesson = getLessonById(id);
        lesson.setStatus("completed");
        lessonMapper.updateById(lesson);
    }

    @Override
    @Transactional
    public void cancelLesson(String id) {
        Lesson lesson = getLessonById(id);
        lesson.setStatus("cancelled");
        lessonMapper.updateById(lesson);
    }

    @Override
    public List<Lesson> getTodayLessons(String tenantId) {
        return lessonMapper.selectList(
                new LambdaQueryWrapper<Lesson>()
                        .eq(Lesson::getTenantId, tenantId)
                        .eq(Lesson::getLessonDate, LocalDate.now())
                        .in(Lesson::getStatus, "scheduled", "in_progress")
                        .orderByAsc(Lesson::getStartTime)
        );
    }

    @Override
    @Transactional
    public Lesson finishLesson(String id, Integer actualDuration, String overallRating, String participationRating, String completionNote) {
        Lesson lesson = getLessonById(id);
        lesson.setStatus("completed");
        lesson.setActualDuration(actualDuration);
        lesson.setOverallRating(overallRating);
        lesson.setParticipationRating(participationRating);
        lesson.setCompletionNote(completionNote);
        lessonMapper.updateById(lesson);
        return lesson;
    }

    @Override
    @Transactional
    public StudentRecord saveStudentRecord(String lessonId, String studentId, Integer focus, Integer participation, Integer interest, Integer understanding, String notes) {
        // 验证课程是否存在
        getLessonById(lessonId);

        // 检查是否已存在记录
        StudentRecord existing = studentRecordMapper.selectOne(
                new LambdaQueryWrapper<StudentRecord>()
                        .eq(StudentRecord::getLessonId, lessonId)
                        .eq(StudentRecord::getStudentId, studentId)
        );

        StudentRecord record;
        if (existing != null) {
            record = existing;
        } else {
            record = new StudentRecord();
            record.setLessonId(lessonId);
            record.setStudentId(studentId);
        }

        record.setFocus(focus);
        record.setParticipation(participation);
        record.setInterest(interest);
        record.setUnderstanding(understanding);
        record.setNotes(notes);

        if (existing != null) {
            studentRecordMapper.updateById(record);
        } else {
            studentRecordMapper.insert(record);
        }

        return record;
    }

    @Override
    public List<StudentRecord> getStudentRecords(String lessonId) {
        // 验证课程是否存在
        getLessonById(lessonId);

        // 获取该课程的所有学生记录
        return studentRecordMapper.selectList(
                new LambdaQueryWrapper<StudentRecord>()
                        .eq(StudentRecord::getLessonId, lessonId)
        );
    }

    @Override
    @Transactional
    public int batchSaveStudentRecords(String lessonId, List<Map<String, Object>> records) {
        int count = 0;
        for (Map<String, Object> recordData : records) {
            String studentId = recordData.get("studentId") != null ? recordData.get("studentId").toString() : null;
            Integer focus = recordData.get("focus") != null ? ((Number) recordData.get("focus")).intValue() : null;
            Integer participation = recordData.get("participation") != null ? ((Number) recordData.get("participation")).intValue() : null;
            Integer interest = recordData.get("interest") != null ? ((Number) recordData.get("interest")).intValue() : null;
            Integer understanding = recordData.get("understanding") != null ? ((Number) recordData.get("understanding")).intValue() : null;
            String notes = (String) recordData.get("notes");

            saveStudentRecord(lessonId, studentId, focus, participation, interest, understanding, notes);
            count++;
        }
        return count;
    }

    @Override
    @Transactional
    public LessonFeedback saveLessonFeedback(String tenantId, String lessonId, String teacherId, Map<String, Object> feedbackData) {
        // 验证课程是否存在
        Lesson lesson = getLessonById(lessonId);

        // 检查是否已存在反馈
        LessonFeedback existing = lessonFeedbackMapper.selectOne(
                new LambdaQueryWrapper<LessonFeedback>()
                        .eq(LessonFeedback::getLessonId, lessonId)
                        .eq(LessonFeedback::getTeacherId, teacherId)
        );

        LessonFeedback feedback;
        if (existing != null) {
            feedback = existing;
        } else {
            feedback = new LessonFeedback();
            feedback.setLessonId(lessonId);
            feedback.setTeacherId(teacherId);
        }

        // 设置反馈数据
        if (feedbackData.get("designQuality") != null) {
            feedback.setDesignQuality(((Number) feedbackData.get("designQuality")).intValue());
        }
        if (feedbackData.get("participation") != null) {
            feedback.setParticipation(((Number) feedbackData.get("participation")).intValue());
        }
        if (feedbackData.get("goalAchievement") != null) {
            feedback.setGoalAchievement(((Number) feedbackData.get("goalAchievement")).intValue());
        }
        if (feedbackData.get("stepFeedbacks") != null) {
            feedback.setStepFeedbacks((String) feedbackData.get("stepFeedbacks"));
        }
        if (feedbackData.get("pros") != null) {
            feedback.setPros((String) feedbackData.get("pros"));
        }
        if (feedbackData.get("suggestions") != null) {
            feedback.setSuggestions((String) feedbackData.get("suggestions"));
        }
        if (feedbackData.get("activitiesDone") != null) {
            feedback.setActivitiesDone((String) feedbackData.get("activitiesDone"));
        }

        if (existing != null) {
            lessonFeedbackMapper.updateById(feedback);
        } else {
            lessonFeedbackMapper.insert(feedback);
        }

        return feedback;
    }

    @Override
    public LessonFeedback getLessonFeedback(String lessonId) {
        return lessonFeedbackMapper.selectOne(
                new LambdaQueryWrapper<LessonFeedback>()
                        .eq(LessonFeedback::getLessonId, lessonId)
        );
    }

}
