type SupabaseRouteClient = {
  from: (table: string) => any;
};

export type MediaSupabaseClient = SupabaseRouteClient;

export type MediaToolContext = {
  userId: string;
  attachments?: Array<{ id: string; title: string; fileUrl: string; mimeType?: string | null }>;
};

const isRecord = (v: unknown): v is Record<string, unknown> =>
  typeof v === "object" && v !== null && !Array.isArray(v);

type ResolvedAttachment = { id: string; title: string; fileUrl: string; mimeType?: string | null };

const resolveAttachment = (ctx: MediaToolContext, ref: string): ResolvedAttachment | null => {
  const s = String(ref || "").trim();
  if (!s) return null;
  const list = Array.isArray(ctx.attachments) ? ctx.attachments : [];
  const byId = list.find((a) => String(a.id) === s);
  if (byId) return { id: String(byId.id), title: String(byId.title || byId.id), fileUrl: String(byId.fileUrl || ""), mimeType: byId.mimeType ?? null };
  const exactTitle = list.find((a) => String(a.title) === s);
  if (exactTitle) return { id: String(exactTitle.id), title: String(exactTitle.title || exactTitle.id), fileUrl: String(exactTitle.fileUrl || ""), mimeType: exactTitle.mimeType ?? null };
  const fuzzy = list.find((a) => String(a.title || "").includes(s) || String(a.fileUrl || "").includes(s));
  if (fuzzy) return { id: String(fuzzy.id), title: String(fuzzy.title || fuzzy.id), fileUrl: String(fuzzy.fileUrl || ""), mimeType: fuzzy.mimeType ?? null };
  return null;
};

const pick = (obj: unknown, key: string) => (isRecord(obj) ? obj[key] : undefined);

export const createMediaServerTools = (args: {
  supabase?: MediaSupabaseClient;
  ctx: MediaToolContext;
  allowedToolIds: Set<string>;
  // 说明：Convex 迁移阶段用于“去 Supabase 化”。如果提供该能力，则完全不依赖 Supabase。
  loadById?: (id: string) => Promise<unknown | null>;
  loadByFileUrl?: (fileUrl: string) => Promise<unknown | null>;
}) => {
  const resolveImageReadTransport = async (toolArgs: Record<string, unknown>) => {
    if (!args.allowedToolIds.has("image_read")) throw new Error("工具未被允许：image_read");

    const assetId = String(toolArgs.assetId ?? "").trim();
    const fileUrl = String(toolArgs.fileUrl ?? "").trim();
    const attachmentRef = String(toolArgs.attachmentRef ?? "").trim();

    const resolved = attachmentRef ? resolveAttachment(args.ctx, attachmentRef) : null;
    const targetAssetId = assetId || resolved?.id || "";
    const targetUrl = fileUrl || resolved?.fileUrl || "";

    let row: unknown = null;
    if (targetAssetId) {
      if (args.loadById) {
        row = await args.loadById(targetAssetId);
      } else {
        if (!args.supabase) throw new Error("缺少 Supabase 数据源（请在 Convex 模式下传入 loadById/loadByFileUrl）");
        const { data, error } = await args.supabase
          .from("media_assets")
          .select("id,file_name,file_url,mime_type,ocr_text,ocr_status,ocr_payload,storage_path,bucket,document_id,workspace_id,deleted_at,purged_at,updated_at")
          .eq("id", targetAssetId)
          .single();
        if (error) {
          throw new Error(isRecord(error) && typeof error.message === "string" ? error.message : "读取图片失败");
        }
        row = data;
      }
    } else if (targetUrl) {
      if (args.loadByFileUrl) {
        row = await args.loadByFileUrl(targetUrl);
      } else {
        if (!args.supabase) throw new Error("缺少 Supabase 数据源（请在 Convex 模式下传入 loadById/loadByFileUrl）");
        const { data, error } = await args.supabase
          .from("media_assets")
          .select("id,file_name,file_url,mime_type,ocr_text,ocr_status,ocr_payload,storage_path,bucket,document_id,workspace_id,deleted_at,purged_at,updated_at")
          .eq("file_url", targetUrl)
          .order("updated_at", { ascending: false })
          .limit(1)
          .maybeSingle();
        if (error) {
          throw new Error(isRecord(error) && typeof error.message === "string" ? error.message : "读取图片失败");
        }
        row = data;
      }
    } else {
      throw new Error("缺少 assetId / fileUrl / attachmentRef");
    }

    if (!row) return { ok: true, found: false };

    const ocrText = String(pick(row, "ocr_text") ?? "");
    const ocrStatus = String(pick(row, "ocr_status") ?? "");
    const mimeType = String(pick(row, "mime_type") ?? "");
    return {
      ok: true,
      found: true,
      asset: {
        id: String(pick(row, "id") ?? ""),
        fileName: String(pick(row, "file_name") ?? ""),
        fileUrl: String(pick(row, "file_url") ?? ""),
        mimeType,
        storagePath: pick(row, "storage_path") ? String(pick(row, "storage_path")) : null,
        bucket: pick(row, "bucket") ? String(pick(row, "bucket")) : null,
        documentId: pick(row, "document_id") ? String(pick(row, "document_id")) : null,
        workspaceId: pick(row, "workspace_id") ? String(pick(row, "workspace_id")) : null,
        deletedAt: pick(row, "deleted_at") ?? null,
        purgedAt: pick(row, "purged_at") ?? null,
        updatedAt: pick(row, "updated_at") ?? null,
      },
      ocrStatus,
      ocrText,
      hasOcrText: Boolean(ocrText.trim()),
      note: ocrText.trim()
        ? "已返回 ocr_text。"
        : "该图片暂未生成 ocr_text（可等待后台 OCR，或后续再补一个 image_ocr 写工具）。",
    };
  };

  return { resolveImageReadTransport };
};
