package com.lesingle.edu.controller.teacher;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lesingle.edu.common.annotation.Log;
import com.lesingle.edu.common.enums.LogModule;
import com.lesingle.edu.common.enums.LogOperationType;
import com.lesingle.edu.common.mapper.ClassMapper;
import com.lesingle.edu.common.mapper.LessonMapper;
import com.lesingle.edu.common.mapper.StudentRecordMapper;
import com.lesingle.edu.common.response.PageResult;
import com.lesingle.edu.common.response.Result;
import com.lesingle.edu.common.security.SecurityUtils;
import com.lesingle.edu.dto.request.LessonCreateRequest;
import com.lesingle.edu.dto.request.LessonProgressRequest;
import com.lesingle.edu.dto.request.LessonUpdateRequest;
import com.lesingle.edu.dto.request.BatchStudentRecordsRequest;
import com.lesingle.edu.dto.request.StudentRecordRequest;
import com.lesingle.edu.dto.response.ClassResponse;
import com.lesingle.edu.dto.response.CourseResponse;
import com.lesingle.edu.dto.response.LessonDetailResponse;
import com.lesingle.edu.dto.response.LessonResponse;
import com.lesingle.edu.dto.response.StudentRecordsResponse;
import com.lesingle.edu.dto.response.StudentRecordResponse;
import com.lesingle.edu.entity.Clazz;
import com.lesingle.edu.entity.CoursePackage;
import com.lesingle.edu.entity.Lesson;
import com.lesingle.edu.entity.LessonFeedback;
import com.lesingle.edu.entity.StudentRecord;
import com.lesingle.edu.mapper.ClazzMapper;
import com.lesingle.edu.mapper.CoursePackageMapper;
import com.lesingle.edu.service.CoursePackageService;
import com.lesingle.edu.service.LessonService;
import com.lesingle.edu.service.SchoolScheduleService;
import com.lesingle.edu.entity.SchedulePlan;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;

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

@Tag(name = "教师端 - 课时管理", description = "教师端课时 API")
@RestController
@RequestMapping("/api/v1/teacher/lessons")
@RequiredArgsConstructor
public class TeacherLessonController {

    private final LessonService lessonService;
    private final LessonMapper lessonMapper;
    private final StudentRecordMapper studentRecordMapper;
    private final CoursePackageMapper courseMapper;
    private final ClazzMapper clazzMapper;
    private final ClassMapper classMapper;
    private final CoursePackageService courseService;
    private final SchoolScheduleService schoolScheduleService;

    @Operation(summary = "创建课时")
    @Log(module = LogModule.LESSON, type = LogOperationType.CREATE, description = "创建课时")
    @PostMapping
    public Result<LessonResponse> createLesson(@Valid @RequestBody LessonCreateRequest request) {
        Long tenantId = SecurityUtils.getCurrentTenantId();
        Lesson lesson = lessonService.createLesson(tenantId, request);
        LessonResponse vo = lessonMapper.toVO(lesson);
        enrichWithCourseAndClass(vo);
        return Result.success(vo);
    }

    @Operation(summary = "更新课时")
    @Log(module = LogModule.LESSON, type = LogOperationType.UPDATE, description = "更新课时")
    @PutMapping("/{id}")
    public Result<LessonResponse> updateLesson(@PathVariable Long id, @RequestBody LessonUpdateRequest request) {
        Lesson lesson = lessonService.updateLesson(id, request);
        return Result.success(lessonMapper.toVO(lesson));
    }

    @Operation(summary = "根据 ID 获取课时（含课程、班级，供上课页面使用）")
    @GetMapping("/{id}")
    public Result<LessonDetailResponse> getLesson(@PathVariable Long id) {
        Long tenantId = SecurityUtils.getCurrentTenantId();
        Lesson lesson = lessonService.getLessonById(id);
        LessonResponse lessonVo = lessonMapper.toVO(lesson);
        enrichWithCourseAndClass(lessonVo);

        LessonDetailResponse detail = new LessonDetailResponse();
        detail.setLesson(lessonVo);

        if (lesson.getCourseId() != null) {
            try {
                CourseResponse courseResp = courseService.getCourseByIdWithLessons(lesson.getCourseId());
                detail.setCourse(courseResp);
            } catch (Exception e) {
                // 课程不存在时留空
            }
        }
        if (lesson.getClassId() != null) {
            Clazz clazz = clazzMapper.selectById(lesson.getClassId());
            if (clazz != null) {
                detail.setClassInfo(classMapper.toVO(clazz));
            }
        }
        // 从排课计划读取 lessonType，供前端判断子课程模式并直接进入对应子课程
        if (lesson.getSchedulePlanId() != null) {
            try {
                SchedulePlan schedule = schoolScheduleService.getScheduleById(lesson.getSchedulePlanId(), tenantId);
                if (schedule != null && schedule.getLessonType() != null) {
                    detail.setLessonType(schedule.getLessonType());
                }
            } catch (Exception e) {
                // 排课不存在或无权访问时忽略
            }
        }
        return Result.success(detail);
    }

    @Operation(summary = "获取我的课时列表")
    @GetMapping
    public Result<PageResult<LessonResponse>> getMyLessons(
            @RequestParam(required = false, defaultValue = "1") Integer pageNum,
            @RequestParam(required = false, defaultValue = "10") Integer pageSize,
            @RequestParam(required = false) String status,
            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate) {
        Long teacherId = SecurityUtils.getCurrentUserId();
        Page<Lesson> page = lessonService.getTeacherLessons(teacherId, pageNum, pageSize, status, startDate, endDate);
        List<LessonResponse> voList = lessonMapper.toVO(page.getRecords());
        voList.forEach(this::enrichWithCourseAndClass);
        return Result.success(PageResult.of(voList, page.getTotal(), page.getCurrent(), page.getSize()));
    }

    @Operation(summary = "开始上课")
    @Log(module = LogModule.LESSON, type = LogOperationType.OTHER, description = "开始上课")
    @PostMapping("/{id}/start")
    public Result<Void> startLesson(@PathVariable Long id) {
        lessonService.startLesson(id);
        return Result.success();
    }

    @Operation(summary = "完成课时")
    @Log(module = LogModule.LESSON, type = LogOperationType.OTHER, description = "完成课时")
    @PostMapping("/{id}/complete")
    public Result<Void> completeLesson(@PathVariable Long id) {
        lessonService.completeLesson(id);
        return Result.success();
    }

    @Operation(summary = "取消课时")
    @Log(module = LogModule.LESSON, type = LogOperationType.OTHER, description = "取消课时")
    @PostMapping("/{id}/cancel")
    public Result<Void> cancelLesson(@PathVariable Long id) {
        lessonService.cancelLesson(id);
        return Result.success();
    }

    @Operation(summary = "退出上课（删除未完成的课时记录）")
    @Log(module = LogModule.LESSON, type = LogOperationType.DELETE, description = "教师退出上课并删除课时")
    @PostMapping("/{id}/abandon")
    public Result<Void> abandonLesson(@PathVariable Long id) {
        Long teacherId = SecurityUtils.getCurrentUserId();
        Long tenantId = SecurityUtils.getCurrentTenantId();
        lessonService.abandonLessonByTeacher(id, teacherId, tenantId);
        return Result.success();
    }

    @Operation(summary = "获取今日课程")
    @GetMapping("/today")
    public Result<List<LessonResponse>> getTodayLessons() {
        Long tenantId = SecurityUtils.getCurrentTenantId();
        List<Lesson> lessons = lessonService.getTodayLessons(tenantId);
        List<LessonResponse> voList = lessonMapper.toVO(lessons);
        voList.forEach(this::enrichWithCourseAndClass);
        return Result.success(voList);
    }

    @Operation(summary = "获取学生记录")
    @GetMapping("/{id}/students/records")
    public Result<StudentRecordsResponse> getStudentRecords(@PathVariable Long id) {
        StudentRecordsResponse response = lessonService.getStudentRecords(id);
        return Result.success(response);
    }

    @Operation(summary = "保存学生记录")
    @Log(module = LogModule.STUDENT_RECORD, type = LogOperationType.CREATE, description = "保存学生记录")
    @PostMapping("/{id}/students/{studentId}/record")
    public Result<StudentRecordResponse> saveStudentRecord(
            @PathVariable Long id,
            @PathVariable Long studentId,
            @RequestBody StudentRecordRequest request) {
        StudentRecord record = lessonService.saveStudentRecord(id, studentId, request);
        return Result.success(studentRecordMapper.toVO(record));
    }

    @Operation(summary = "批量保存学生记录")
    @Log(module = LogModule.STUDENT_RECORD, type = LogOperationType.CREATE, description = "批量保存学生记录")
    @PostMapping("/{id}/students/batch-records")
    public Result<List<StudentRecordResponse>> batchSaveStudentRecords(
            @PathVariable Long id,
            @RequestBody BatchStudentRecordsRequest request) {
        List<StudentRecordRequest> requests = request.getRecords() != null ? request.getRecords() : List.of();
        List<StudentRecord> records = lessonService.batchSaveStudentRecords(id, requests);
        List<StudentRecordResponse> voList = studentRecordMapper.toVO(records);
        return Result.success(voList);
    }

    @Operation(summary = "获取课时反馈")
    @GetMapping("/{id}/feedback")
    public Result<LessonFeedback> getLessonFeedback(@PathVariable Long id) {
        LessonFeedback feedback = lessonService.getLessonFeedback(id);
        return Result.success(feedback != null ? feedback : null);
    }

    @Operation(summary = "提交课时反馈")
    @Log(module = LogModule.LESSON_FEEDBACK, type = LogOperationType.CREATE, description = "提交课时反馈")
    @PostMapping("/{id}/feedback")
    public Result<LessonFeedback> submitFeedback(
            @PathVariable Long id,
            @RequestBody com.lesingle.edu.dto.request.LessonFeedbackRequest request) {
        Long teacherId = SecurityUtils.getCurrentUserId();
        LessonFeedback feedback = lessonService.submitFeedback(id, teacherId, request.getContent(), request.getRating());
        return Result.success(feedback);
    }

    @Operation(summary = "保存课时进度")
    @Log(module = LogModule.LESSON, type = LogOperationType.UPDATE, description = "保存课时进度")
    @PutMapping("/{id}/progress")
    public Result<Void> saveLessonProgress(
            @PathVariable Long id,
            @RequestBody LessonProgressRequest request) {
        lessonService.saveLessonProgress(id, request);
        return Result.success();
    }

    @Operation(summary = "获取课时进度")
    @GetMapping("/{id}/progress")
    public Result<LessonResponse> getLessonProgress(@PathVariable Long id) {
        Lesson lesson = lessonService.getLessonProgress(id);
        LessonResponse vo = lessonMapper.toVO(lesson);
        enrichWithCourseAndClass(vo);
        return Result.success(vo);
    }

    /**
     * 为 LessonResponse 补充课程名称和班级名称
     */
    private void enrichWithCourseAndClass(LessonResponse vo) {
        if (vo == null) return;
        if (vo.getCourseId() != null) {
            CoursePackage course = courseMapper.selectById(vo.getCourseId());
            vo.setCourseName(course != null ? course.getName() : null);
        }
        if (vo.getClassId() != null) {
            Clazz clazz = clazzMapper.selectById(vo.getClassId());
            vo.setClassName(clazz != null ? clazz.getName() : null);
        }
    }

    @Operation(summary = "从排课开始上课")
    @Log(module = LogModule.LESSON, type = LogOperationType.OTHER, description = "从排课开始上课")
    @PostMapping("/from-schedule/{schedulePlanId}/start")
    public Result<LessonResponse> startLessonFromSchedule(@PathVariable Long schedulePlanId) {
        Long teacherId = SecurityUtils.getCurrentUserId();
        Long tenantId = SecurityUtils.getCurrentTenantId();

        // 验证排课存在且属于当前租户
        SchedulePlan schedule = schoolScheduleService.getScheduleById(schedulePlanId, tenantId);

        // 从排课开始上课
        Lesson lesson = lessonService.startLessonFromSchedule(schedulePlanId, teacherId);
        return Result.success(lessonMapper.toVO(lesson));
    }

    @Operation(summary = "从排课创建课时")
    @Log(module = LogModule.LESSON, type = LogOperationType.CREATE, description = "从排课创建课时")
    @PostMapping("/from-schedule/{schedulePlanId}")
    public Result<LessonResponse> createLessonFromSchedule(@PathVariable Long schedulePlanId) {
        Long teacherId = SecurityUtils.getCurrentUserId();
        Long tenantId = SecurityUtils.getCurrentTenantId();

        // 验证排课存在且属于当前租户
        schoolScheduleService.getScheduleById(schedulePlanId, tenantId);

        // 从排课创建课时
        Lesson lesson = lessonService.createLessonFromSchedule(schedulePlanId, teacherId);
        return Result.success(lessonMapper.toVO(lesson));
    }

}
