import { zipSync, strToU8 } from "fflate";
import { adminForbidden, isAdminRequest } from "../../../lib/admin-auth";
import { ensureSchema, getRawDb, getUploadBucket } from "../../../lib/mvp-db";
import { parseResultScreenshotKeys } from "../../../lib/result-screenshots";

function safeName(value: string) {
  return value.replace(/[\\/:*?"<>|\r\n]/g, "_").trim().slice(0, 60) || "KOC";
}

function csvCell(value: unknown) {
  const text = String(value ?? "");
  return `"${text.replaceAll('"', '""')}"`;
}

export async function GET(request: Request) {
  if (!(await isAdminRequest(request))) return adminForbidden();
  try {
    await ensureSchema();
    const taskId = new URL(request.url).searchParams.get("task")?.trim();
    if (!taskId) {
      return Response.json({ error: "缺少任务参数" }, { status: 400 });
    }
    const task = await getRawDb()
      .prepare("SELECT name, task_type FROM tasks WHERE id = ?")
      .bind(taskId)
      .first<{ name: string; task_type: string }>();
    if (!task || task.task_type !== "screenshot_collect") {
      return Response.json({ error: "没有找到截图回收任务" }, { status: 404 });
    }
    const rows = await getRawDb()
      .prepare(
        `SELECT d.id, d.result_screenshot_key, d.result_submitted_at,
                d.claimed_at, c.source_row, c.title, p.name AS partner_name,
                cl.claimant_name
         FROM distributions d
         JOIN contents c ON c.id = d.content_id
         JOIN partners p ON p.id = d.partner_id
         LEFT JOIN claims cl ON cl.id = d.claim_id
         WHERE d.task_id = ?
         ORDER BY COALESCE(c.source_row, 999999), d.claimed_at, d.id`,
      )
      .bind(taskId)
      .all<{
        id: string;
        result_screenshot_key: string | null;
        result_submitted_at: string | null;
        claimed_at: string;
        source_row: number | null;
        title: string;
        partner_name: string;
        claimant_name: string | null;
      }>();
    const files: Record<string, Uint8Array> = {};
    const manifest = [
      ["序号", "搜索关键词", "领取人", "领取时间", "提交时间", "文件名"],
    ];
    let exported = 0;
    for (const [rowIndex, row] of rows.results.entries()) {
      const fileNames: string[] = [];
      const screenshotKeys = row.result_submitted_at
        ? parseResultScreenshotKeys(row.result_screenshot_key)
        : [];
      for (const [imageIndex, screenshotKey] of screenshotKeys.entries()) {
        const object = await getUploadBucket().get(screenshotKey);
        if (!object) continue;
        const extension = screenshotKey.split(".").at(-1) || "jpg";
        const fileName = `${String(row.source_row ?? rowIndex + 1).padStart(3, "0")}-${safeName(row.claimant_name || row.partner_name)}-${imageIndex + 1}.${extension}`;
        files[fileName] = new Uint8Array(await object.arrayBuffer());
        fileNames.push(fileName);
        exported += 1;
      }
      manifest.push([
        String(row.source_row ?? ""),
        row.title,
        row.claimant_name || row.partner_name,
        row.claimed_at,
        row.result_submitted_at || "",
        fileNames.join("；"),
      ]);
    }
    files["回收清单.csv"] = strToU8(
      `\uFEFF${manifest.map((cells) => cells.map(csvCell).join(",")).join("\r\n")}`,
    );
    const archive = zipSync(files, { level: 0 });
    const headers = new Headers({
      "Content-Type": "application/zip",
      "Content-Disposition": `attachment; filename*=UTF-8''${encodeURIComponent(`${safeName(task.name)}-截图回收.zip`)}`,
      "Cache-Control": "private, no-store",
      "X-KOC-Exported-Count": String(exported),
    });
    const body = archive.buffer.slice(
      archive.byteOffset,
      archive.byteOffset + archive.byteLength,
    ) as ArrayBuffer;
    return new Response(body, { headers });
  } catch (error) {
    return Response.json(
      { error: error instanceof Error ? error.message : "截图打包失败" },
      { status: 500 },
    );
  }
}
