import {
  init_ids,
  newId
} from "./chunk-F4WUVOLE.js";
import {
  init_clock,
  nowMs,
  toIso
} from "./chunk-HFDLUBWN.js";
import {
  getDrizzle,
  init_drizzle
} from "./chunk-RII4M3J2.js";
import {
  schema_exports
} from "./chunk-DDJOPRB7.js";

// src/db/files.ts
init_drizzle();
init_ids();
init_clock();
import { eq, and, desc, sql, gt, lt } from "drizzle-orm";
function hydrate(row) {
  return {
    id: row.id,
    type: "file",
    filename: row.filename,
    mime_type: row.content_type,
    size_bytes: row.size,
    // All local files are downloadable. Anthropic sets downloadable: false
    // for user-uploaded inputs, but we always serve them (UI needs access).
    downloadable: true,
    scope: row.scope_type && row.scope_id ? { type: row.scope_type, id: row.scope_id } : null,
    created_at: toIso(row.created_at)
  };
}
function createFile(input) {
  const db = getDrizzle();
  const id = newId("file");
  const now = nowMs();
  db.insert(schema_exports.files).values({
    id,
    filename: input.filename,
    size: input.size,
    content_type: input.content_type,
    storage_path: input.storage_path,
    scope_type: input.scope?.type ?? null,
    scope_id: input.scope?.id ?? null,
    container_path: input.container_path ?? null,
    content_hash: input.content_hash ?? null,
    created_at: now
  }).run();
  return {
    id,
    type: "file",
    filename: input.filename,
    mime_type: input.content_type,
    size_bytes: input.size,
    downloadable: true,
    scope: input.scope ?? null,
    created_at: toIso(now)
  };
}
function findFileByContainerPath(scopeId, containerPath, contentHash) {
  const db = getDrizzle();
  const row = db.select().from(schema_exports.files).where(
    and(
      eq(schema_exports.files.scope_id, scopeId),
      eq(schema_exports.files.container_path, containerPath),
      eq(schema_exports.files.content_hash, contentHash)
    )
  ).get();
  return row ?? null;
}
function getFile(id) {
  const db = getDrizzle();
  const row = db.select().from(schema_exports.files).where(eq(schema_exports.files.id, id)).get();
  return row ?? null;
}
function getFileRecord(id) {
  const row = getFile(id);
  return row ? hydrate(row) : null;
}
function listFiles(opts) {
  const db = getDrizzle();
  const limit = opts?.limit ?? 100;
  const cursorClause = opts?.after_id ? sql` AND f.id > ${opts.after_id}` : opts?.before_id ? sql` AND f.id < ${opts.before_id}` : sql``;
  if (opts?.scope_id) {
    const rows2 = db.all(
      sql`SELECT f.* FROM files f
        LEFT JOIN files f2
          ON f.scope_id = f2.scope_id
          AND f.container_path = f2.container_path
          AND f.container_path IS NOT NULL
          AND (f2.created_at > f.created_at OR (f2.created_at = f.created_at AND f2.id > f.id))
        WHERE f.scope_id = ${opts.scope_id} AND f2.id IS NULL${cursorClause}
        ORDER BY f.id DESC LIMIT ${limit + 1}`
    );
    const hasMore2 = rows2.length > limit;
    if (hasMore2) rows2.pop();
    const records2 = rows2.map(hydrate);
    return { data: records2, has_more: hasMore2, first_id: records2[0]?.id ?? null, last_id: records2[records2.length - 1]?.id ?? null };
  }
  let cursorCondition;
  if (opts?.after_id) {
    cursorCondition = gt(schema_exports.files.id, opts.after_id);
  } else if (opts?.before_id) {
    cursorCondition = lt(schema_exports.files.id, opts.before_id);
  }
  const query = cursorCondition ? db.select().from(schema_exports.files).where(cursorCondition).orderBy(desc(schema_exports.files.id)).limit(limit + 1) : db.select().from(schema_exports.files).orderBy(desc(schema_exports.files.id)).limit(limit + 1);
  const rows = query.all();
  const hasMore = rows.length > limit;
  if (hasMore) rows.pop();
  const records = rows.map(hydrate);
  return { data: records, has_more: hasMore, first_id: records[0]?.id ?? null, last_id: records[records.length - 1]?.id ?? null };
}
function countFilesForScope(scopeId) {
  const db = getDrizzle();
  const result = db.all(
    sql`SELECT COUNT(*) as cnt FROM files WHERE scope_id = ${scopeId}`
  );
  return result[0]?.cnt ?? 0;
}
function updateFileStoragePath(id, storagePath) {
  const db = getDrizzle();
  db.update(schema_exports.files).set({ storage_path: storagePath }).where(eq(schema_exports.files.id, id)).run();
}
function deleteFileRecord(id) {
  const db = getDrizzle();
  const row = getFile(id);
  if (!row) return null;
  db.delete(schema_exports.files).where(eq(schema_exports.files.id, id)).run();
  return { id, type: "file_deleted" };
}

export {
  createFile,
  findFileByContainerPath,
  getFile,
  getFileRecord,
  listFiles,
  countFilesForScope,
  updateFileStoragePath,
  deleteFileRecord
};
