import {
  ensureSchema,
  getRawDb,
  getUploadBucket,
  uid,
} from "../../../lib/mvp-db";
import {
  partnerOptions,
  withPartnerCors,
} from "../../../lib/partner-cors";
import {
  MAX_RESULT_SCREENSHOTS,
  parseResultScreenshotKeys,
  serializeResultScreenshotKeys,
} from "../../../lib/result-screenshots";
import { creatorScreenshotMcpUrl } from "../../../lib/creator-screenshot-access";
import {
  extractCreatorMetricsFromMcp,
  resolveCollectionMcpConfig,
  type CollectionMcpBindings,
} from "../../../lib/mcp-collection-client";
import { getRuntimeEnv } from "../../../lib/runtime-env";

async function readUpload(request: Request) {
  const contentType = request.headers.get("content-type") ?? "";
  if (contentType.startsWith("multipart/form-data")) {
    const form = await request.formData();
    const file = form.get("file");
    if (!(file instanceof File)) return null;
    return {
      taskToken: String(form.get("taskToken") ?? "").trim(),
      claimToken: String(form.get("claimToken") ?? "").trim(),
      delegationToken: String(form.get("delegationToken") ?? "").trim(),
      distributionId: String(form.get("distributionId") ?? "").trim(),
      uploadKind: String(form.get("uploadKind") ?? "publish").trim(),
      fileName: file.name,
      fileType: file.type,
      fileBytes: await file.arrayBuffer(),
    };
  }
  const encodedName = request.headers.get("x-koc-file-name") ?? "screenshot.jpg";
  let fileName = "screenshot.jpg";
  try {
    fileName = decodeURIComponent(encodedName);
  } catch {
    fileName = "screenshot.jpg";
  }
  return {
    taskToken: String(request.headers.get("x-koc-task") ?? "").trim(),
    claimToken: String(request.headers.get("x-koc-claim") ?? "").trim(),
    delegationToken: String(
      request.headers.get("x-koc-delegation") ?? "",
    ).trim(),
    distributionId: String(
      request.headers.get("x-koc-distribution") ?? "",
    ).trim(),
    uploadKind: String(
      request.headers.get("x-koc-upload-kind") ?? "publish",
    ).trim(),
    fileName,
    fileType: contentType.split(";")[0].trim(),
    fileBytes: await request.arrayBuffer(),
  };
}

async function handlePost(request: Request) {
  try {
    await ensureSchema();
    const upload = await readUpload(request);
    if (
      !upload ||
      (!upload.claimToken && !upload.delegationToken) ||
      (!upload.delegationToken && !upload.taskToken) ||
      !upload.distributionId ||
      upload.fileBytes.byteLength === 0
    ) {
      return Response.json({ error: "请选择需要上传的截图" }, { status: 400 });
    }
    if (
      !upload.fileType.startsWith("image/") ||
      upload.fileBytes.byteLength > 8_000_000
    ) {
      return Response.json(
        { error: "仅支持8MB以内的图片" },
        { status: 400 },
      );
    }
    const isCreatorCenter = upload.uploadKind === "creator-center";
    const isTaskResult = upload.uploadKind === "task-result";
    if (!["publish", "creator-center", "task-result"].includes(upload.uploadKind)) {
      return Response.json({ error: "不支持的截图类型" }, { status: 400 });
    }
    const assignment = upload.delegationToken
      ? await getRawDb()
          .prepare(
            `SELECT d.id, d.publish_url, d.result_screenshot_key, t.task_type
             FROM distributions d
             JOIN delegation_bundles b ON b.id = d.delegation_bundle_id
             JOIN tasks t ON t.id = d.task_id
             WHERE d.id = ?
               AND b.share_token = ?
               AND b.status = 'active'`,
          )
          .bind(upload.distributionId, upload.delegationToken)
          .first<{ id: string; publish_url: string | null; result_screenshot_key: string | null; task_type: string }>()
      : await getRawDb()
          .prepare(
            `SELECT d.id, d.publish_url, d.result_screenshot_key, t.task_type
             FROM distributions d
             JOIN claims c ON c.id = d.claim_id
             JOIN tasks t ON t.id = d.task_id
             WHERE d.id = ?
               AND c.claim_token = ?
               AND t.share_token = ?
               AND c.task_id = t.id`,
          )
          .bind(upload.distributionId, upload.claimToken, upload.taskToken)
          .first<{ id: string; publish_url: string | null; result_screenshot_key: string | null; task_type: string }>();
    if (!assignment) {
      return Response.json({ error: "笔记与领取凭证不匹配" }, { status: 403 });
    }
    if (isCreatorCenter && !assignment.publish_url) {
      return Response.json(
        { error: "请先回填这篇笔记的发布信息" },
        { status: 409 },
      );
    }
    if (isTaskResult && assignment.task_type !== "screenshot_collect") {
      return Response.json({ error: "当前任务不支持截图结果回填" }, { status: 400 });
    }
    if (!isTaskResult && assignment.task_type === "screenshot_collect") {
      return Response.json({ error: "截图回收任务请上传任务结果截图" }, { status: 400 });
    }
    const existingResultKeys = isTaskResult
      ? parseResultScreenshotKeys(assignment.result_screenshot_key)
      : [];
    if (isTaskResult && existingResultKeys.length >= MAX_RESULT_SCREENSHOTS) {
      return Response.json(
        { error: `每份任务最多上传${MAX_RESULT_SCREENSHOTS}张截图` },
        { status: 409 },
      );
    }
    const extension =
      upload.fileName.split(".").at(-1)?.replace(/[^a-zA-Z0-9]/g, "") || "jpg";
    const key = isTaskResult
      ? `task-results/${upload.distributionId}/${uid("shot")}.${extension}`
      : isCreatorCenter
      ? `creator-center/${upload.distributionId}/${uid("shot")}.${extension}`
      : `publish-evidence/${upload.distributionId}/${uid("shot")}.${extension}`;
    await getUploadBucket().put(key, upload.fileBytes, {
      httpMetadata: { contentType: upload.fileType },
    });
    if (isTaskResult) {
      await getRawDb()
        .prepare(
          `UPDATE distributions SET
            result_screenshot_key = ?,
            updated_at = CURRENT_TIMESTAMP
           WHERE id = ?`,
        )
        .bind(
          serializeResultScreenshotKeys([...existingResultKeys, key]),
          upload.distributionId,
        )
        .run();
    } else if (isCreatorCenter) {
      await getRawDb()
        .prepare(
          `UPDATE distributions SET
            screenshot_key = ?,
            ocr_status = CASE
              WHEN exposure IS NOT NULL AND views IS NOT NULL THEN ocr_status
              ELSE 'processing'
            END,
            updated_at = CURRENT_TIMESTAMP
           WHERE id = ?`,
        )
        .bind(key, upload.distributionId)
        .run();
      try {
        const metrics = await extractCreatorMetricsFromMcp(
          creatorScreenshotMcpUrl(request, upload.distributionId, key),
          resolveCollectionMcpConfig(
            getRuntimeEnv() as unknown as CollectionMcpBindings,
          ),
        );
        await getRawDb()
          .prepare(
            `UPDATE distributions SET exposure = ?, views = ?,
               ocr_status = 'success', updated_at = CURRENT_TIMESTAMP
             WHERE id = ?`,
          )
          .bind(metrics.exposure, metrics.views, upload.distributionId)
          .run();
        return Response.json({
          uploaded: true,
          exposure: metrics.exposure,
          views: metrics.views,
          ocrStatus: "success",
          kind: "creator-center",
        });
      } catch (error) {
        console.error("[KOC LOOP] creator screenshot OCR failed", {
          distributionId: upload.distributionId,
          detail: error instanceof Error ? error.message : String(error),
        });
        await getRawDb()
          .prepare(
            `UPDATE distributions SET ocr_status = 'failed', updated_at = CURRENT_TIMESTAMP WHERE id = ?`,
          )
          .bind(upload.distributionId)
          .run();
      }
    } else {
      await getRawDb()
        .prepare(
          `UPDATE distributions SET
            publish_screenshot_key = ?,
            updated_at = CURRENT_TIMESTAMP
           WHERE id = ?`,
        )
        .bind(key, upload.distributionId)
        .run();
    }
    return Response.json({
      uploaded: true,
      screenshotCount: isTaskResult ? existingResultKeys.length + 1 : undefined,
      kind: isTaskResult
        ? "task-result"
        : isCreatorCenter
          ? "creator-center"
          : "publish",
      ocrStatus: isCreatorCenter ? "failed" : undefined,
    });
  } catch (error) {
    return Response.json(
      { error: error instanceof Error ? error.message : "上传失败" },
      { status: 500 },
    );
  }
}

export async function POST(request: Request) {
  return withPartnerCors(request, await handlePost(request));
}

export async function OPTIONS(request: Request) {
  return partnerOptions(request);
}
