import { NextRequest, NextResponse } from "next/server";
import { db } from "@/lib/db";
import { getServerSession } from "next-auth";
import { authOptions } from "@/lib/auth";
import { writeFile, mkdir } from "fs/promises";
import { existsSync } from "fs";
import path from "path";
import { randomUUID } from "crypto";

const UPLOAD_DIR = path.join(process.cwd(), "public", "uploads");

function getType(mime: string): "image" | "video" | "document" {
  if (mime.startsWith("image/")) return "image";
  if (mime.startsWith("video/")) return "video";
  return "document";
}

async function getDimensions(filePath: string, mime: string): Promise<{ width?: number; height?: number }> {
  if (!mime.startsWith("image/")) return {};
  try {
    const sharp = (await import("sharp")).default;
    const meta = await sharp(filePath).metadata();
    return { width: meta.width, height: meta.height };
  } catch {
    return {};
  }
}

// GET - list media
export async function GET(req: NextRequest) {
  const session = await getServerSession(authOptions);
  if (!session) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });

  const { searchParams } = new URL(req.url);
  const type = searchParams.get("type"); // image | video | document
  const q = searchParams.get("q");
  const limit = Math.min(parseInt(searchParams.get("limit") || "60"), 200);

  const items = await db.mediaItem.findMany({
    where: {
      ...(type ? { type } : {}),
      ...(q ? { originalName: { contains: q } } : {}),
    },
    orderBy: { createdAt: "desc" },
    take: limit,
  });
  return NextResponse.json({ items });
}

// POST - upload
export async function POST(req: NextRequest) {
  const session = await getServerSession(authOptions);
  if (!session) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });

  try {
    const formData = await req.formData();
    const files = formData.getAll("files").filter((f): f is File => f instanceof File);
    if (files.length === 0) return NextResponse.json({ error: "No files provided" }, { status: 400 });

    if (!existsSync(UPLOAD_DIR)) await mkdir(UPLOAD_DIR, { recursive: true });

    const created = [];
    for (const file of files) {
      const ext = path.extname(file.name) || "";
      const safeExt = ext.toLowerCase().replace(/[^a-z0-9.]/g, "");
      const filename = `${Date.now()}-${randomUUID().slice(0, 8)}${safeExt}`;
      const filePath = path.join(UPLOAD_DIR, filename);
      const buffer = Buffer.from(await file.arrayBuffer());
      await writeFile(filePath, buffer);

      const mime = file.type || "application/octet-stream";
      const { width, height } = await getDimensions(filePath, mime);

      const item = await db.mediaItem.create({
        data: {
          filename,
          originalName: file.name,
          url: `/uploads/${filename}`,
          mimeType: mime,
          size: file.size,
          width,
          height,
          type: getType(mime),
        },
      });
      created.push(item);
    }

    return NextResponse.json({ items: created });
  } catch (e) {
    console.error("Upload error:", e);
    return NextResponse.json({ error: "Upload failed" }, { status: 500 });
  }
}
