/**
 * M6 资源附件库 - 数据访问层
 */
import "server-only";
import { db } from "@/shared/db";
import { lessonPlanAttachments } from "@/shared/db/schema";
import { and, eq, desc } from "drizzle-orm";
import type { AttachmentType } from "./lib/type-guards";
import { isAttachmentType } from "./lib/type-guards";

/** 附件记录 */
export interface LessonPlanAttachment {
  id: string;
  planId: string;
  blockId?: string;
  fileId: string;
  displayName: string;
  attachmentType: AttachmentType;
  uploadedBy: string;
  createdAt: Date;
}

/**
 * 查询课案的所有附件
 */
export async function getAttachmentsByPlanId(
  planId: string,
): Promise<LessonPlanAttachment[]> {
  const rows = await db
    .select()
    .from(lessonPlanAttachments)
    .where(eq(lessonPlanAttachments.planId, planId))
    .orderBy(desc(lessonPlanAttachments.createdAt));

  return rows.map(mapRowToAttachment);
}

/**
 * 查询特定 Block 的附件
 */
export async function getAttachmentsByBlockId(
  planId: string,
  blockId: string,
): Promise<LessonPlanAttachment[]> {
  const rows = await db
    .select()
    .from(lessonPlanAttachments)
    .where(
      and(
        eq(lessonPlanAttachments.planId, planId),
        eq(lessonPlanAttachments.blockId, blockId),
      ),
    )
    .orderBy(desc(lessonPlanAttachments.createdAt));

  return rows.map(mapRowToAttachment);
}

/**
 * 添加附件
 */
export async function createAttachment(
  input: {
    planId: string;
    blockId?: string;
    fileId: string;
    displayName: string;
    attachmentType?: AttachmentType;
  },
  uploadedBy: string,
): Promise<LessonPlanAttachment> {
  const [row] = await db.insert(lessonPlanAttachments).values({
    planId: input.planId,
    blockId: input.blockId,
    fileId: input.fileId,
    displayName: input.displayName,
    attachmentType: input.attachmentType ?? "reference",
    uploadedBy,
  });
  const insertedId = row.insertId;
  const all = await getAttachmentsByPlanId(input.planId);
  const created = all.find((a) => a.id === String(insertedId));
  if (!created) throw new Error("ATTACHMENT_CREATE_FAILED");
  return created;
}

/**
 * 删除附件
 */
export async function deleteAttachment(
  attachmentId: string,
): Promise<void> {
  await db
    .delete(lessonPlanAttachments)
    .where(eq(lessonPlanAttachments.id, attachmentId));
}

/**
 * 更新附件类型
 */
export async function updateAttachmentType(
  attachmentId: string,
  attachmentType: AttachmentType,
): Promise<void> {
  await db
    .update(lessonPlanAttachments)
    .set({ attachmentType })
    .where(eq(lessonPlanAttachments.id, attachmentId));
}

/**
 * 按 ID 获取附件
 */
export async function getAttachmentById(
  id: string,
): Promise<LessonPlanAttachment | null> {
  const rows = await db
    .select()
    .from(lessonPlanAttachments)
    .where(eq(lessonPlanAttachments.id, id))
    .limit(1);
  return rows.length === 0 ? null : mapRowToAttachment(rows[0]!);
}

function mapRowToAttachment(
  row: typeof lessonPlanAttachments.$inferSelect,
): LessonPlanAttachment {
  const attachmentType = isAttachmentType(row.attachmentType)
    ? row.attachmentType
    : "reference";
  return {
    id: row.id,
    planId: row.planId,
    blockId: row.blockId ?? undefined,
    fileId: row.fileId,
    displayName: row.displayName,
    attachmentType,
    uploadedBy: row.uploadedBy,
    createdAt: row.createdAt,
  };
}
