import { NextResponse } from "next/server";

import { BUCKETS, DATABASE_ID, TABLES, type Job, type JobFile } from "@/lib/appwrite/schema";
import { createAdminClient } from "@/lib/appwrite/server";
import { requireTenant } from "@/lib/appwrite/tenant-guard";

/**
 * Server-side download proxy. The Appwrite bucket files are scoped to the
 * job's two teams (clinic + lab) and the lab's frontend domain doesn't carry
 * an Appwrite session cookie, so a direct browser → Appwrite link 401s. We
 * authenticate the caller via the lab session, verify they actually have
 * access to the job, then stream the file out with a forced attachment
 * disposition.
 */
export async function GET(
  _request: Request,
  { params }: { params: Promise<{ jobId: string; fileId: string }> },
) {
  const { jobId, fileId } = await params;

  let ctx;
  try {
    ctx = await requireTenant();
  } catch {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  const { tablesDB, storage } = createAdminClient();

  let job: Job;
  let file: JobFile;
  try {
    const [j, f] = await Promise.all([
      tablesDB.getRow(DATABASE_ID, TABLES.jobs, jobId) as Promise<unknown>,
      tablesDB.getRow(DATABASE_ID, TABLES.jobFiles, fileId) as Promise<unknown>,
    ]);
    job = j as Job;
    file = f as JobFile;
  } catch {
    return NextResponse.json({ error: "Not found" }, { status: 404 });
  }

  if (file.jobId !== jobId) {
    return NextResponse.json({ error: "Not found" }, { status: 404 });
  }
  if (ctx.tenantId !== job.clinicTenantId && ctx.tenantId !== job.labTenantId) {
    return NextResponse.json({ error: "Forbidden" }, { status: 403 });
  }
  if (file.archivedAt) {
    return NextResponse.json(
      { error: "Dosya arşivlendi, indirilebilir kopya yok." },
      { status: 410 },
    );
  }

  const buf = (await storage.getFileDownload(BUCKETS.jobFiles, file.fileId)) as
    | ArrayBuffer
    | Buffer;
  const body =
    buf instanceof ArrayBuffer ? new Uint8Array(buf) : new Uint8Array(buf);

  // Quote the filename so spaces / non-ASCII don't break the header.
  const safeName = file.name.replace(/["\\]/g, "_");
  return new NextResponse(body, {
    status: 200,
    headers: {
      "Content-Type": "application/octet-stream",
      "Content-Disposition": `attachment; filename="${safeName}"; filename*=UTF-8''${encodeURIComponent(file.name)}`,
      "Cache-Control": "private, no-store",
    },
  });
}
