/**
 * M9 日历视图 - 数据访问层
 *
 * 按日期范围查询教师备课记录，用于周历/月历展示。
 * 关联查询 createdAt/updatedAt/submittedAt 用于在日历上标记事件。
 */
import "server-only";
import { db } from "@/shared/db";
import { lessonPlans, lessonPlanVersions, lessonPlanReviewRecords } from "@/shared/db/schema";
import { and, eq, gte, lte, asc } from "drizzle-orm";
import type { LessonPlanStatus } from "./types";

/** 日历事件 */
export interface LessonPlanCalendarEvent {
  id: string;
  planId: string;
  title: string;
  status: LessonPlanStatus;
  eventType: "created" | "updated" | "version_saved" | "submitted" | "published" | "reviewed";
  occurredAt: Date;
  creatorId: string;
  versionNo?: number;
}

/**
 * 按日期范围查询教师备课日历事件
 */
export async function getCalendarEvents(
  teacherId: string,
  startDate: Date,
  endDate: Date,
): Promise<LessonPlanCalendarEvent[]> {
  const events: LessonPlanCalendarEvent[] = [];

  // 1. 课案创建/更新事件
  const planRows = await db
    .select({
      id: lessonPlans.id,
      title: lessonPlans.title,
      status: lessonPlans.status,
      createdAt: lessonPlans.createdAt,
      updatedAt: lessonPlans.updatedAt,
      creatorId: lessonPlans.creatorId,
    })
    .from(lessonPlans)
    .where(
      and(
        eq(lessonPlans.creatorId, teacherId),
        gte(lessonPlans.updatedAt, startDate),
        lte(lessonPlans.updatedAt, endDate),
      ),
    )
    .orderBy(asc(lessonPlans.updatedAt));

  for (const p of planRows) {
    // 创建事件
    if (p.createdAt >= startDate && p.createdAt <= endDate) {
      events.push({
        id: `${p.id}-created`,
        planId: p.id,
        title: p.title,
        status: p.status as LessonPlanStatus,
        eventType: "created",
        occurredAt: p.createdAt,
        creatorId: p.creatorId,
      });
    }
    // 更新事件（如果不是同一天创建的）
    if (p.updatedAt > p.createdAt) {
      events.push({
        id: `${p.id}-updated`,
        planId: p.id,
        title: p.title,
        status: p.status as LessonPlanStatus,
        eventType: "updated",
        occurredAt: p.updatedAt,
        creatorId: p.creatorId,
      });
    }
    // 提交/发布事件
    if (p.status === "submitted" as LessonPlanStatus || p.status === "published" as LessonPlanStatus) {
      events.push({
        id: `${p.id}-${p.status}`,
        planId: p.id,
        title: p.title,
        status: p.status as LessonPlanStatus,
        eventType: p.status === "submitted" ? "submitted" : "published",
        occurredAt: p.updatedAt,
        creatorId: p.creatorId,
      });
    }
  }

  // 2. 版本保存事件
  const versionRows = await db
    .select({
      id: lessonPlanVersions.id,
      planId: lessonPlanVersions.planId,
      versionNo: lessonPlanVersions.versionNo,
      createdAt: lessonPlanVersions.createdAt,
      title: lessonPlans.title,
      creatorId: lessonPlanVersions.creatorId,
    })
    .from(lessonPlanVersions)
    .innerJoin(lessonPlans, eq(lessonPlanVersions.planId, lessonPlans.id))
    .where(
      and(
        eq(lessonPlanVersions.creatorId, teacherId),
        gte(lessonPlanVersions.createdAt, startDate),
        lte(lessonPlanVersions.createdAt, endDate),
      ),
    )
    .orderBy(asc(lessonPlanVersions.createdAt));

  for (const v of versionRows) {
    events.push({
      id: v.id,
      planId: v.planId,
      title: v.title,
      status: "draft" as LessonPlanStatus,
      eventType: "version_saved",
      occurredAt: v.createdAt,
      creatorId: v.creatorId,
      versionNo: v.versionNo,
    });
  }

  // 3. 审核事件
  const reviewRows = await db
    .select({
      id: lessonPlanReviewRecords.id,
      planId: lessonPlanReviewRecords.planId,
      decision: lessonPlanReviewRecords.decision,
      createdAt: lessonPlanReviewRecords.createdAt,
      reviewerId: lessonPlanReviewRecords.reviewerId,
      title: lessonPlans.title,
    })
    .from(lessonPlanReviewRecords)
    .innerJoin(lessonPlans, eq(lessonPlanReviewRecords.planId, lessonPlans.id))
    .where(
      and(
        eq(lessonPlanReviewRecords.reviewerId, teacherId),
        gte(lessonPlanReviewRecords.createdAt, startDate),
        lte(lessonPlanReviewRecords.createdAt, endDate),
      ),
    );

  for (const r of reviewRows) {
    events.push({
      id: r.id,
      planId: r.planId,
      title: r.title,
      status: "approved" as LessonPlanStatus,
      eventType: "reviewed",
      occurredAt: r.createdAt,
      creatorId: r.reviewerId,
    });
  }

  // 按时间排序
  return events.sort((a, b) => a.occurredAt.getTime() - b.occurredAt.getTime());
}

/**
 * 按日期分组日历事件
 */
export function groupEventsByDate(
  events: LessonPlanCalendarEvent[],
): Map<string, LessonPlanCalendarEvent[]> {
  const map = new Map<string, LessonPlanCalendarEvent[]>();
  for (const e of events) {
    const dateKey = e.occurredAt.toISOString().split("T")[0]!;
    const list = map.get(dateKey) ?? [];
    list.push(e);
    map.set(dateKey, list);
  }
  return map;
}
