package com.lesingle.edu.controller.school;

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.annotation.RequireRole;
import com.lesingle.edu.common.enums.UserRole;
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.SchedulePlanCreateRequest;
import com.lesingle.edu.dto.request.SchedulePlanUpdateRequest;
import com.lesingle.edu.dto.request.ScheduleCreateByClassesRequest;
import com.lesingle.edu.dto.response.CalendarViewResponse;
import com.lesingle.edu.dto.response.ConflictCheckResult;
import com.lesingle.edu.dto.response.LessonTypeInfo;
import com.lesingle.edu.dto.response.SchedulePlanResponse;
import com.lesingle.edu.entity.SchedulePlan;
import com.lesingle.edu.service.SchoolScheduleService;
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;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 学校端 - 排课管理
 */
@Tag(name = "学校端 - 排课管理", description = "School Schedule APIs")
@RestController
@RequestMapping("/api/v1/school/schedules")
@RequiredArgsConstructor
@RequireRole(UserRole.SCHOOL)
public class SchoolScheduleController {

    private final SchoolScheduleService schoolScheduleService;

    @GetMapping
    @Operation(summary = "获取排课列表")
    public Result<PageResult<SchedulePlanResponse>> getSchedules(
            @RequestParam(required = false, defaultValue = "1") Integer pageNum,
            @RequestParam(required = false, defaultValue = "10") Integer pageSize,
            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate,
            @RequestParam(required = false) Long classId,
            @RequestParam(required = false) Long teacherId,
            @RequestParam(required = false) String status) {

        Long tenantId = SecurityUtils.getCurrentTenantId();
        Page<SchedulePlan> page = schoolScheduleService.getSchedulePage(
                tenantId, pageNum, pageSize, startDate, endDate, classId, teacherId, status);

        List<SchedulePlanResponse> records = page.getRecords().stream()
                .map(schoolScheduleService::toSchedulePlanResponse)
                .collect(Collectors.toList());

        return Result.success(PageResult.of(records, page.getTotal(), page.getCurrent(), page.getSize()));
    }

    @GetMapping("/timetable")
    @Operation(summary = "获取课程表")
    public Result<Map<String, Object>> getTimetable(
            @RequestParam(required = false) Long classId,
            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate) {

        Long tenantId = SecurityUtils.getCurrentTenantId();
        return Result.success(schoolScheduleService.getTimetable(tenantId, classId, startDate, endDate));
    }

    @GetMapping("/{id}")
    @Operation(summary = "获取排课详情")
    public Result<SchedulePlanResponse> getSchedule(@PathVariable Long id) {
        Long tenantId = SecurityUtils.getCurrentTenantId();
        SchedulePlan schedule = schoolScheduleService.getScheduleById(id, tenantId);
        return Result.success(schoolScheduleService.toSchedulePlanResponse(schedule));
    }

    @PostMapping
    @Operation(summary = "创建排课")
    @Log(module = LogModule.SCHEDULE, type = LogOperationType.CREATE, description = "创建排课计划")
    public Result<List<SchedulePlanResponse>> createSchedule(@Valid @RequestBody SchedulePlanCreateRequest request) {
        Long tenantId = SecurityUtils.getCurrentTenantId();
        List<SchedulePlan> plans = schoolScheduleService.createSchedule(tenantId, request);
        List<SchedulePlanResponse> result = plans.stream()
                .map(schoolScheduleService::toSchedulePlanResponse)
                .collect(Collectors.toList());
        return Result.success(result);
    }

    @PutMapping("/{id}")
    @Operation(summary = "更新排课")
    @Log(module = LogModule.SCHEDULE, type = LogOperationType.UPDATE, description = "更新排课计划")
    public Result<SchedulePlanResponse> updateSchedule(
            @PathVariable Long id,
            @RequestBody SchedulePlanUpdateRequest request) {

        Long tenantId = SecurityUtils.getCurrentTenantId();
        SchedulePlan schedule = schoolScheduleService.updateSchedule(id, tenantId, request);
        return Result.success(schoolScheduleService.toSchedulePlanResponse(schedule));
    }

    @DeleteMapping("/{id}")
    @Operation(summary = "取消排课")
    @Log(module = LogModule.SCHEDULE, type = LogOperationType.DELETE, description = "取消排课计划")
    public Result<Void> cancelSchedule(@PathVariable Long id) {
        Long tenantId = SecurityUtils.getCurrentTenantId();
        schoolScheduleService.cancelSchedule(id, tenantId);
        return Result.success();
    }

    @DeleteMapping("/{id}/force")
    @Operation(summary = "删除排课（物理删除）")
    @Log(module = LogModule.SCHEDULE, type = LogOperationType.DELETE, description = "删除排课记录")
    public Result<Void> deleteSchedule(@PathVariable Long id) {
        Long tenantId = SecurityUtils.getCurrentTenantId();
        schoolScheduleService.deleteSchedule(id, tenantId);
        return Result.success();
    }

    @PostMapping("/batch")
    @Operation(summary = "批量创建排课")
    @Log(module = LogModule.SCHEDULE, type = LogOperationType.CREATE, description = "批量创建排课计划")
    public Result<List<SchedulePlanResponse>> batchCreateSchedules(
            @RequestBody List<@Valid SchedulePlanCreateRequest> requests) {

        Long tenantId = SecurityUtils.getCurrentTenantId();
        List<SchedulePlan> plans = schoolScheduleService.batchCreateSchedules(tenantId, requests);
        List<SchedulePlanResponse> result = plans.stream()
                .map(schoolScheduleService::toSchedulePlanResponse)
                .collect(Collectors.toList());
        return Result.success(result);
    }

    @PostMapping("/check-conflict")
    @Operation(summary = "检测排课冲突")
    public Result<ConflictCheckResult> checkConflict(
            @RequestParam Long classId,
            @RequestParam(required = false) Long teacherId,
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate scheduledDate,
            @RequestParam String scheduledTime) {

        Long tenantId = SecurityUtils.getCurrentTenantId();
        ConflictCheckResult result = schoolScheduleService.checkConflict(
                tenantId, classId, teacherId, scheduledDate, scheduledTime);
        return Result.success(result);
    }

    @GetMapping("/course-packages/{id}/lesson-types")
    @Operation(summary = "获取课程包的课程类型列表")
    @RequireRole({UserRole.SCHOOL, UserRole.TEACHER})
    public Result<List<LessonTypeInfo>> getCoursePackageLessonTypes(@PathVariable Long id) {
        Long tenantId = SecurityUtils.getCurrentTenantId();
        return Result.success(schoolScheduleService.getCoursePackageLessonTypes(tenantId, id));
    }

    @PostMapping("/batch-by-classes")
    @Operation(summary = "批量创建排课（按班级）")
    @Log(module = LogModule.SCHEDULE, type = LogOperationType.CREATE, description = "按班级批量创建排课")
    public Result<List<SchedulePlanResponse>> createSchedulesByClasses(
            @Valid @RequestBody ScheduleCreateByClassesRequest request) {
        Long tenantId = SecurityUtils.getCurrentTenantId();
        List<SchedulePlan> plans = schoolScheduleService.createSchedulesByClasses(tenantId, request);
        List<SchedulePlanResponse> result = plans.stream()
                .map(schoolScheduleService::toSchedulePlanResponse)
                .collect(Collectors.toList());
        return Result.success(result);
    }

    @GetMapping("/calendar")
    @Operation(summary = "获取日历视图数据")
    public Result<CalendarViewResponse> getCalendarViewData(
            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate,
            @RequestParam(required = false) Long classId,
            @RequestParam(required = false) Long teacherId) {
        Long tenantId = SecurityUtils.getCurrentTenantId();
        CalendarViewResponse response = schoolScheduleService.getCalendarViewData(
                tenantId, startDate, endDate, classId, teacherId);
        return Result.success(response);
    }

}
