import { getSession } from "@/lib/auth";
import { storage, type Bucket } from "@/lib/storage";

const CONTENT_TYPES: Record<string, string> = {
  ".jpg": "image/jpeg",
  ".jpeg": "image/jpeg",
  ".png": "image/png",
  ".webp": "image/webp",
  ".avif": "image/avif",
};

function contentTypeFor(key: string) {
  const ext = key.slice(key.lastIndexOf(".")).toLowerCase();
  return CONTENT_TYPES[ext] ?? "application/octet-stream";
}

function parseBucket(bucket: string): Bucket | null {
  return bucket === "public" || bucket === "private" ? bucket : null;
}

// Serves files from DATA_DIR/storage.
export async function GET(
  _req: Request,
  ctx: RouteContext<"/api/storage/[bucket]/[...key]">
) {
  const { bucket: rawBucket, key: keyParts } = await ctx.params;
  const bucket = parseBucket(rawBucket);
  if (!bucket) return new Response("Not found", { status: 404 });

  // Originals stay private — admin session required
  if (bucket === "private" && !(await getSession())) {
    return new Response("Unauthorized", { status: 401 });
  }

  const key = keyParts.join("/");
  try {
    const body = await storage.get(bucket, key);
    return new Response(new Uint8Array(body), {
      headers: {
        "Content-Type": contentTypeFor(key),
        "X-Content-Type-Options": "nosniff",
        "Cache-Control": bucket === "public" ? "public, max-age=31536000, immutable" : "no-store",
      },
    });
  } catch {
    return new Response("Not found", { status: 404 });
  }
}

const MAX_UPLOAD_SIZE = 60 * 1024 * 1024; // matches /api/upload/presign

// Direct browser upload target (see storage.uploadTarget).
// Only originals land here — public variants are written by the pipeline itself.
export async function PUT(
  req: Request,
  ctx: RouteContext<"/api/storage/[bucket]/[...key]">
) {
  if (!(await getSession())) return new Response("Unauthorized", { status: 401 });

  const { bucket: rawBucket, key: keyParts } = await ctx.params;
  const key = keyParts.join("/");
  if (rawBucket !== "private" || !key.startsWith("originals/")) {
    return new Response("Not found", { status: 404 });
  }

  const body = Buffer.from(await req.arrayBuffer());
  if (body.byteLength > MAX_UPLOAD_SIZE) {
    return new Response("Payload too large", { status: 413 });
  }
  await storage.put("private", key, body);
  return new Response(null, { status: 200 });
}
