package com.lesingle.edu.service;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
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 java.time.LocalDate;
import java.util.List;
import java.util.Map;

/**
 * 学校端排课服务接口
 */
public interface SchoolScheduleService extends IService<SchedulePlan> {

    /**
     * 创建排课 (支持重复排课)
     *
     * @param tenantId 租户 ID
     * @param request  创建请求
     * @return 创建的排课列表 (重复排课会返回多条)
     */
    List<SchedulePlan> createSchedule(Long tenantId, SchedulePlanCreateRequest request);

    /**
     * 更新排课
     *
     * @param id      排课 ID
     * @param tenantId 租户 ID
     * @param request 更新请求
     * @return 更新后的排课
     */
    SchedulePlan updateSchedule(Long id, Long tenantId, SchedulePlanUpdateRequest request);

    /**
     * 取消排课
     *
     * @param id       排课 ID
     * @param tenantId 租户 ID
     */
    void cancelSchedule(Long id, Long tenantId);

    /**
     * 删除排课（物理删除，仅限已取消状态）
     *
     * @param id       排课 ID
     * @param tenantId 租户 ID
     */
    void deleteSchedule(Long id, Long tenantId);

    /**
     * 获取排课详情
     *
     * @param id       排课 ID
     * @param tenantId 租户 ID
     * @return 排课详情
     */
    SchedulePlan getScheduleById(Long id, Long tenantId);

    /**
     * 分页获取排课列表
     *
     * @param tenantId  租户 ID
     * @param pageNum   页码
     * @param pageSize  每页大小
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @param classId   班级 ID
     * @param teacherId 教师 ID
     * @param status    状态
     * @return 分页结果
     */
    Page<SchedulePlan> getSchedulePage(Long tenantId, Integer pageNum, Integer pageSize,
                                       LocalDate startDate, LocalDate endDate,
                                       Long classId, Long teacherId, String status);

    /**
     * 获取课程表 (按日期分组)
     *
     * @param tenantId  租户 ID
     * @param classId   班级 ID (可选)
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @return 课程表数据 (按日期分组)
     */
    Map<String, Object> getTimetable(Long tenantId, Long classId, LocalDate startDate, LocalDate endDate);

    /**
     * 批量创建排课
     *
     * @param tenantId 租户 ID
     * @param requests 创建请求列表
     * @return 创建的排课列表
     */
    List<SchedulePlan> batchCreateSchedules(Long tenantId, List<SchedulePlanCreateRequest> requests);

    /**
     * 检测冲突
     *
     * @param tenantId      租户 ID
     * @param classId       班级 ID
     * @param teacherId     教师 ID
     * @param scheduledDate 排课日期
     * @param scheduledTime 时间段
     * @return 冲突检测结果
     */
    ConflictCheckResult checkConflict(Long tenantId, Long classId, Long teacherId,
                                      LocalDate scheduledDate, String scheduledTime);

    /**
     * 获取课程包的课程类型列表
     *
     * @param tenantId       租户 ID
     * @param coursePackageId 课程包 ID
     * @return 课程类型信息列表
     */
    List<LessonTypeInfo> getCoursePackageLessonTypes(Long tenantId, Long coursePackageId);

    /**
     * 批量创建排课（按班级）
     *
     * @param tenantId 租户 ID
     * @param request 批量创建请求
     * @return 创建的排课列表
     */
    List<SchedulePlan> createSchedulesByClasses(Long tenantId, ScheduleCreateByClassesRequest request);

    /**
     * 获取日历视图数据
     *
     * @param tenantId  租户 ID
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @param classId   班级 ID (可选)
     * @param teacherId 教师 ID (可选)
     * @return 日历视图数据
     */
    CalendarViewResponse getCalendarViewData(Long tenantId, LocalDate startDate, LocalDate endDate,
                                              Long classId, Long teacherId);

    /**
     * 转换为 Response（含班级名、课程名、教师名等展示字段）
     *
     * @param plan 排课实体
     * @return 排课响应
     */
    SchedulePlanResponse toSchedulePlanResponse(SchedulePlan plan);

}
