import {
  deleteFile,
  getMaxFileSize,
  readFile,
  storeFile
} from "./chunk-STPT3SWU.js";
import {
  createFile,
  deleteFileRecord,
  getFile,
  getFileRecord,
  listFiles,
  updateFileStoragePath
} from "./chunk-BGBPOR4J.js";
import {
  assertResourceTenant
} from "./chunk-K7DLILHK.js";
import {
  jsonOk,
  routeWrap
} from "./chunk-QSHK4MUE.js";
import {
  getDb,
  init_client
} from "./chunk-TLEKKGH7.js";
import {
  badRequest,
  notFound
} from "./chunk-EZYKRG4W.js";

// src/handlers/anthropic-compat/files.ts
init_client();
function assertFileTenantByScope(auth, scopeType, scopeId) {
  if (!scopeId || scopeType !== "session") {
    if (!auth.isGlobalAdmin) throw notFound("file not found");
    return;
  }
  const row = getDb().prepare(`SELECT tenant_id FROM sessions WHERE id = ?`).get(scopeId);
  if (!row) throw notFound("file not found");
  assertResourceTenant(auth, row.tenant_id, "file not found");
}
function handleUploadFile(request) {
  return routeWrap(request, async ({ auth, request: req }) => {
    const contentType = req.headers.get("content-type") ?? "";
    let filename;
    let data;
    let fileContentType;
    if (contentType.includes("multipart/form-data")) {
      const formData = await req.formData();
      const file = formData.get("file");
      if (!file || !(file instanceof File)) {
        throw badRequest("Missing 'file' field in multipart form data");
      }
      filename = file.name || "upload";
      fileContentType = file.type || "application/octet-stream";
      const ab = await file.arrayBuffer();
      data = Buffer.from(ab);
    } else {
      const url2 = new URL(req.url);
      filename = url2.searchParams.get("filename") || req.headers.get("x-filename") || "upload";
      fileContentType = contentType || "application/octet-stream";
      const ab = await req.arrayBuffer();
      data = Buffer.from(ab);
    }
    if (data.length === 0) {
      throw badRequest("Empty file");
    }
    const maxSize = getMaxFileSize();
    if (data.length > maxSize) {
      throw badRequest(`File too large: ${data.length} bytes (max ${maxSize})`);
    }
    const url = new URL(req.url);
    const scopeId = url.searchParams.get("scope_id");
    const scopeType = url.searchParams.get("scope_type") || "session";
    const scope = scopeId ? { type: scopeType, id: scopeId } : void 0;
    assertFileTenantByScope(auth, scope?.type ?? null, scope?.id ?? null);
    const record = createFile({
      filename,
      size: data.length,
      content_type: fileContentType,
      storage_path: "",
      // placeholder — set after store
      scope
    });
    const storagePath = storeFile(record.id, filename, data);
    updateFileStoragePath(record.id, storagePath);
    return jsonOk(record, 201);
  });
}
function handleListFiles(request) {
  return routeWrap(request, async ({ auth, request: req }) => {
    const url = new URL(req.url);
    const limit = Number(url.searchParams.get("limit") || "100");
    const scope_id = url.searchParams.get("scope_id") || void 0;
    const after_id = url.searchParams.get("after_id") || void 0;
    const before_id = url.searchParams.get("before_id") || void 0;
    if (scope_id) {
      const row = getDb().prepare(`SELECT tenant_id FROM sessions WHERE id = ?`).get(scope_id);
      if (!row) throw notFound(`session not found: ${scope_id}`);
      assertResourceTenant(auth, row.tenant_id, `session not found: ${scope_id}`);
    } else if (!auth.isGlobalAdmin) {
      throw badRequest("scope_id is required for tenant-scoped listings");
    }
    const result = listFiles({ limit, scope_id, after_id, before_id });
    return jsonOk(result);
  });
}
function handleGetFile(request, fileId) {
  return routeWrap(request, async ({ auth }) => {
    const record = getFileRecord(fileId);
    if (!record) throw notFound(`file not found: ${fileId}`);
    assertFileTenantByScope(auth, record.scope?.type ?? null, record.scope?.id ?? null);
    return jsonOk(record);
  });
}
function handleGetFileContent(request, fileId) {
  return routeWrap(request, async ({ auth }) => {
    const row = getFile(fileId);
    if (!row) throw notFound(`file not found: ${fileId}`);
    assertFileTenantByScope(auth, row.scope_type, row.scope_id);
    if (row.storage_path.startsWith("remote:")) {
      const remoteFileId = row.storage_path.slice(7);
      const { resolveAnthropicKey } = await import("./providers/upstream-keys.js");
      const resolved = resolveAnthropicKey({
        sessionId: row.scope_id ?? void 0
      });
      if (!resolved) throw notFound("file content unavailable (no API key)");
      const upstream = await fetch(
        `https://api.anthropic.com/v1/files/${remoteFileId}/content`,
        {
          headers: {
            "x-api-key": resolved.value,
            "anthropic-version": "2023-06-01",
            "anthropic-beta": "managed-agents-2026-04-01,files-api-2025-04-14"
          },
          signal: AbortSignal.timeout(3e4)
        }
      );
      if (!upstream.ok) throw notFound(`file content unavailable (upstream ${upstream.status})`);
      return new Response(upstream.body, {
        headers: {
          "Content-Type": row.content_type,
          "Content-Disposition": `attachment; filename="${row.filename}"`
        }
      });
    }
    const data = readFile(row.storage_path);
    return new Response(data, {
      headers: {
        "Content-Type": row.content_type,
        "Content-Disposition": `attachment; filename="${row.filename}"`,
        "Content-Length": String(data.length)
      }
    });
  });
}
function handleDeleteFile(request, fileId) {
  return routeWrap(request, async ({ auth }) => {
    const row = getFile(fileId);
    if (!row) throw notFound(`file not found: ${fileId}`);
    assertFileTenantByScope(auth, row.scope_type, row.scope_id);
    deleteFile(row.storage_path);
    const result = deleteFileRecord(fileId);
    return jsonOk(result);
  });
}

export {
  handleUploadFile,
  handleListFiles,
  handleGetFile,
  handleGetFileContent,
  handleDeleteFile
};
