import { getRuntimeEnv } from "../../../lib/runtime-env";
import {
  ensureSchema,
  getRawDb,
  getUploadBucket,
} from "../../../lib/mvp-db";
import {
  downloadFeishuMedia,
  type FeishuBindings,
} from "../../../lib/feishu-client";
import {
  partnerOptions,
  withPartnerCors,
} from "../../../lib/partner-cors";
import { parseResultScreenshotKeys } from "../../../lib/result-screenshots";

const env = getRuntimeEnv();

type StoredAsset = {
  index: number;
  key: string;
  fileToken?: string;
};

function textValue(value: string | null, maxLength = 100) {
  return String(value ?? "").trim().slice(0, maxLength);
}

function findAsset(value: string, imageIndex: number) {
  try {
    const assets = JSON.parse(value) as StoredAsset[];
    return Array.isArray(assets)
      ? assets.find(
          (asset) =>
            asset.index === imageIndex &&
            typeof asset.key === "string" &&
            (asset.key.startsWith("content-assets/") ||
              asset.key.startsWith("task-assets/")) &&
            (asset.fileToken === undefined ||
              typeof asset.fileToken === "string"),
        )
      : undefined;
  } catch {
    return undefined;
  }
}

async function handleGet(request: Request) {
  try {
    await ensureSchema();
    const url = new URL(request.url);
    const taskToken = textValue(url.searchParams.get("task"));
    const claimToken = textValue(url.searchParams.get("claim"));
    const delegationToken = textValue(url.searchParams.get("share"));
    const distributionId = textValue(url.searchParams.get("distribution"));
    const imageIndex = Number(url.searchParams.get("index"));
    const imageKind = textValue(url.searchParams.get("kind"), 20);
    if (
      (!delegationToken && (!taskToken || !claimToken)) ||
      !distributionId ||
      !Number.isInteger(imageIndex) ||
      imageIndex < 1
    ) {
      return Response.json({ error: "图片链接不完整" }, { status: 400 });
    }
    const row = delegationToken
      ? await getRawDb()
          .prepare(
            `SELECT c.image_assets,
                    d.result_screenshot_key,
                    d.publish_screenshot_key,
                    d.screenshot_key
             FROM distributions d
             JOIN contents c ON c.id = d.content_id
             JOIN delegation_bundles b ON b.id = d.delegation_bundle_id
             WHERE d.id = ?
               AND b.share_token = ?
               AND b.status = 'active'`,
          )
          .bind(distributionId, delegationToken)
          .first<{
            image_assets: string;
            result_screenshot_key: string | null;
            publish_screenshot_key: string | null;
            screenshot_key: string | null;
          }>()
      : await getRawDb()
          .prepare(
            `SELECT c.image_assets,
                    d.result_screenshot_key,
                    d.publish_screenshot_key,
                    d.screenshot_key
             FROM distributions d
             JOIN contents c ON c.id = d.content_id
             JOIN claims cl ON cl.id = d.claim_id
             JOIN tasks t ON t.id = d.task_id
             WHERE d.id = ?
               AND cl.claim_token = ?
               AND t.share_token = ?
               AND cl.task_id = t.id`,
          )
          .bind(distributionId, claimToken, taskToken)
          .first<{
            image_assets: string;
            result_screenshot_key: string | null;
            publish_screenshot_key: string | null;
            screenshot_key: string | null;
          }>();
    const asset =
      imageKind === "result"
        ? row
          ? {
              index: imageIndex,
              key: parseResultScreenshotKeys(row.result_screenshot_key)[
                imageIndex - 1
              ],
            }
          : undefined
        : imageKind === "publish"
          ? row?.publish_screenshot_key?.startsWith("publish-evidence/")
            ? { index: 1, key: row.publish_screenshot_key }
            : undefined
        : imageKind === "creator"
          ? row?.screenshot_key?.startsWith("creator-center/")
            ? { index: 1, key: row.screenshot_key }
            : undefined
        : row
          ? findAsset(row.image_assets, imageIndex)
          : undefined;
    if (!asset?.key) {
      return Response.json({ error: "没有找到这张图片" }, { status: 404 });
    }
    const bucket = getUploadBucket();
    let object = await bucket.get(asset.key);
    if (!object && asset.fileToken) {
      const media = await downloadFeishuMedia(
        asset.fileToken,
        env as unknown as FeishuBindings,
      );
      await bucket.put(asset.key, media.bytes, {
        httpMetadata: { contentType: media.contentType },
        customMetadata: { source: "feishu-api" },
      });
      object = await bucket.get(asset.key);
    }
    if (!object) {
      return Response.json({ error: "图片同步失败，请稍后重试" }, { status: 404 });
    }
    const headers = new Headers();
    object.writeHttpMetadata(headers);
    headers.set("Cache-Control", "private, max-age=3600");
    headers.set("Content-Disposition", `inline; filename="note-${imageIndex}"`);
    return new Response(await object.arrayBuffer(), { headers });
  } catch (error) {
    return Response.json(
      { error: error instanceof Error ? error.message : "图片读取失败" },
      { status: 500 },
    );
  }
}

export async function GET(request: Request) {
  return withPartnerCors(request, await handleGet(request));
}

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