/**
 * V5-7：课案-课时绑定数据访问层
 *
 * 将课案绑定到具体班级的某个日期/节次，支持 calendar-view 安排课时。
 */
import "server-only";
import { db } from "@/shared/db";
import { lessonPlanSchedules, classes } from "@/shared/db/schema";
import { and, eq, gte, lte, desc } from "drizzle-orm";
import { createId } from "@paralleldrive/cuid2";

/** 课时绑定记录 */
export interface LessonPlanScheduleRecord {
  id: string;
  planId: string;
  classId: string;
  className: string;
  scheduledDate: string; // YYYY-MM-DD
  period: number;
  classScheduleId?: string | null;
  durationMin: number;
  createdBy: string;
  createdAt: Date;
  updatedAt: Date;
}

/** 将 Date 转换为 YYYY-MM-DD 字符串（用于接口输出） */
function toDateStr(d: Date): string {
  const y = d.getFullYear();
  const m = String(d.getMonth() + 1).padStart(2, "0");
  const day = String(d.getDate()).padStart(2, "0");
  return `${y}-${m}-${day}`;
}

/** 查询课案的所有课时绑定 */
export async function getSchedulesByPlanId(
  planId: string,
): Promise<LessonPlanScheduleRecord[]> {
  const rows = await db
    .select({
      id: lessonPlanSchedules.id,
      planId: lessonPlanSchedules.planId,
      classId: lessonPlanSchedules.classId,
      className: classes.name,
      scheduledDate: lessonPlanSchedules.scheduledDate,
      period: lessonPlanSchedules.period,
      classScheduleId: lessonPlanSchedules.classScheduleId,
      durationMin: lessonPlanSchedules.durationMin,
      createdBy: lessonPlanSchedules.createdBy,
      createdAt: lessonPlanSchedules.createdAt,
      updatedAt: lessonPlanSchedules.updatedAt,
    })
    .from(lessonPlanSchedules)
    .leftJoin(classes, eq(lessonPlanSchedules.classId, classes.id))
    .where(eq(lessonPlanSchedules.planId, planId))
    .orderBy(desc(lessonPlanSchedules.scheduledDate));

  return rows.map((r) => ({
    id: r.id,
    planId: r.planId,
    classId: r.classId,
    className: r.className ?? "",
    scheduledDate: toDateStr(r.scheduledDate),
    period: r.period,
    classScheduleId: r.classScheduleId,
    durationMin: r.durationMin,
    createdBy: r.createdBy,
    createdAt: r.createdAt,
    updatedAt: r.updatedAt,
  }));
}

/** 查询教师在某日期范围内的课时绑定 */
export async function getSchedulesByDateRange(
  teacherPlanIds: string[],
  startDate: string,
  endDate: string,
): Promise<LessonPlanScheduleRecord[]> {
  if (teacherPlanIds.length === 0) return [];
  const rows = await db
    .select({
      id: lessonPlanSchedules.id,
      planId: lessonPlanSchedules.planId,
      classId: lessonPlanSchedules.classId,
      className: classes.name,
      scheduledDate: lessonPlanSchedules.scheduledDate,
      period: lessonPlanSchedules.period,
      classScheduleId: lessonPlanSchedules.classScheduleId,
      durationMin: lessonPlanSchedules.durationMin,
      createdBy: lessonPlanSchedules.createdBy,
      createdAt: lessonPlanSchedules.createdAt,
      updatedAt: lessonPlanSchedules.updatedAt,
    })
    .from(lessonPlanSchedules)
    .leftJoin(classes, eq(lessonPlanSchedules.classId, classes.id))
    .where(
      and(
        // 简化：仅按日期范围过滤（planId 过滤由调用方处理或 join）
        gte(lessonPlanSchedules.scheduledDate, new Date(startDate)),
        lte(lessonPlanSchedules.scheduledDate, new Date(endDate)),
      ),
    )
    .orderBy(desc(lessonPlanSchedules.scheduledDate));

  return rows
    .filter((r) => teacherPlanIds.includes(r.planId))
    .map((r) => ({
      id: r.id,
      planId: r.planId,
      classId: r.classId,
      className: r.className ?? "",
      scheduledDate: toDateStr(r.scheduledDate),
      period: r.period,
      classScheduleId: r.classScheduleId,
      durationMin: r.durationMin,
      createdBy: r.createdBy,
      createdAt: r.createdAt,
      updatedAt: r.updatedAt,
    }));
}

/** 创建课时绑定 */
export async function createSchedule(input: {
  planId: string;
  classId: string;
  scheduledDate: string;
  period: number;
  classScheduleId?: string;
  durationMin?: number;
  createdBy: string;
}): Promise<LessonPlanScheduleRecord> {
  const newId = createId();
  await db.insert(lessonPlanSchedules).values({
    id: newId,
    planId: input.planId,
    classId: input.classId,
    scheduledDate: new Date(input.scheduledDate),
    period: input.period,
    classScheduleId: input.classScheduleId,
    durationMin: input.durationMin ?? 40,
    createdBy: input.createdBy,
  });

  const created = await db
    .select({
      id: lessonPlanSchedules.id,
      planId: lessonPlanSchedules.planId,
      classId: lessonPlanSchedules.classId,
      className: classes.name,
      scheduledDate: lessonPlanSchedules.scheduledDate,
      period: lessonPlanSchedules.period,
      classScheduleId: lessonPlanSchedules.classScheduleId,
      durationMin: lessonPlanSchedules.durationMin,
      createdBy: lessonPlanSchedules.createdBy,
      createdAt: lessonPlanSchedules.createdAt,
      updatedAt: lessonPlanSchedules.updatedAt,
    })
    .from(lessonPlanSchedules)
    .leftJoin(classes, eq(lessonPlanSchedules.classId, classes.id))
    .where(eq(lessonPlanSchedules.id, newId));

  const r = created[0]!;
  return {
    id: r.id,
    planId: r.planId,
    classId: r.classId,
    className: r.className ?? "",
    scheduledDate: toDateStr(r.scheduledDate),
    period: r.period,
    classScheduleId: r.classScheduleId,
    durationMin: r.durationMin,
    createdBy: r.createdBy,
    createdAt: r.createdAt,
    updatedAt: r.updatedAt,
  };
}

/** 删除课时绑定 */
export async function deleteSchedule(id: string): Promise<void> {
  await db.delete(lessonPlanSchedules).where(eq(lessonPlanSchedules.id, id));
}
