import { existsSync } from "node:fs";
import { readFile } from "node:fs/promises";
import path from "node:path";
import { NextResponse } from "next/server";
import { auth } from "@/core/auth/auth";
import { getStorage } from "@/core/storage/storage";

/**
 * Media download — tenant-scoped keys only.
 * Query: ?key=tenants/<tenantId>/...
 *
 * Images are publicly readable so studio sites and portfolio pages can render
 * without a session. Non-image assets still require an authenticated member.
 */
export async function GET(request: Request) {
  const key = new URL(request.url).searchParams.get("key")?.trim();
  if (!key || key.includes("..") || !key.startsWith("tenants/")) {
    return NextResponse.json({ error: "Invalid key" }, { status: 400 });
  }

  const parts = key.split("/");
  const tenantId = parts[1];
  if (!tenantId || parts.length < 3) {
    return NextResponse.json({ error: "Invalid key" }, { status: 400 });
  }

  const mime = guessMime(key);
  const isPublicImage = mime.startsWith("image/");

  if (!isPublicImage) {
    const session = await auth();
    if (!session?.user?.id) {
      return NextResponse.json({ error: "Unauthenticated" }, { status: 401 });
    }

    const allowed = session.user.tenantMemberships?.some(
      (m) => m.tenantId === tenantId && m.status === "active",
    );
    const isAdmin =
      session.user.platformRole === "super_admin" ||
      session.user.platformRole === "platform_admin";

    if (!allowed && !isAdmin) {
      return NextResponse.json({ error: "Forbidden" }, { status: 403 });
    }
  }

  // Avoid `instanceof LocalStorageService` — Next production bundles can
  // duplicate the class, so instanceof fails and media returns 501.
  const storage = getStorage() as {
    resolveAbsolutePath?: (storageKey: string, tenantId: string) => string;
  };

  try {
    const absolute =
      typeof storage.resolveAbsolutePath === "function"
        ? storage.resolveAbsolutePath(key, tenantId)
        : path.join(process.cwd(), ".data", "storage", key);

    if (!existsSync(absolute)) {
      return NextResponse.json({ error: "Not found" }, { status: 404 });
    }

    const buffer = await readFile(absolute);

    return new NextResponse(buffer, {
      status: 200,
      headers: {
        "Content-Type": mime,
        "Content-Length": String(buffer.byteLength),
        "Cache-Control": isPublicImage
          ? "public, max-age=300, stale-while-revalidate=86400"
          : "private, max-age=60",
        "X-Content-Type-Options": "nosniff",
      },
    });
  } catch {
    return NextResponse.json({ error: "Not found" }, { status: 404 });
  }
}

function guessMime(key: string): string {
  const lower = key.toLowerCase();
  if (lower.endsWith(".png")) return "image/png";
  if (lower.endsWith(".jpg") || lower.endsWith(".jpeg")) return "image/jpeg";
  if (lower.endsWith(".webp")) return "image/webp";
  if (lower.endsWith(".avif")) return "image/avif";
  if (lower.endsWith(".gif")) return "image/gif";
  if (lower.endsWith(".pdf")) return "application/pdf";
  return "application/octet-stream";
}
