import { prisma } from "@/lib/prisma";
import { getAdminUser } from "@/lib/auth";
import { getUniqueAlbumSlug } from "@/lib/slugify";
import { NextResponse } from "next/server";

const UPLOAD_ENDPOINT = "http://167.71.224.75:8501/upload";
// Do NOT use https://quality-web-developer.com:8501/upload
// unless you have configured SSL on port 8501.

const serializeBigInt = (data: any) =>
  JSON.parse(
    JSON.stringify(data, (_, value) =>
      typeof value === "bigint" ? value.toString() : value
    )
  );

async function uploadToExternalServer(
  file: File,
  folder: string = "gallery-albums"
): Promise<string> {
  const formData = new FormData();

  formData.append("folder", folder);
  formData.append("file", file);

  const response = await fetch(UPLOAD_ENDPOINT, {
    method: "POST",
    body: formData,
    cache: "no-store",
  });

  const responseText = await response.text();

  if (!response.ok) {
    throw new Error(`Upload failed (${response.status})`);
  }

  let result: {
    success: boolean;
    url?: string;
    error?: string;
    message?: string;
  };

  try {
    result = JSON.parse(responseText);
  } catch {
    throw new Error("Invalid JSON response from upload server");
  }

  if (!result.success) {
    throw new Error(result.error || result.message || "Upload failed");
  }

  if (!result.url) {
    throw new Error("Upload server did not return file URL");
  }

  return result.url;
}

// GET: list all albums (admin view -> includes inactive), with image counts
export async function GET() {
  const admin = await getAdminUser();

  if (!admin) {
    return NextResponse.json(
      { success: false, message: "Unauthorized" },
      { status: 401 }
    );
  }

  try {
    const albums = await prisma.cms_gallery_albums.findMany({
      orderBy: { sort_order: "asc" },
      include: {
        _count: { select: { images: true } },
      },
    });

    return NextResponse.json({
      success: true,
      data: serializeBigInt(albums),
    });
  } catch (error: any) {
    return NextResponse.json(
      { success: false, message: error.message || "Failed to fetch albums" },
      { status: 500 }
    );
  }
}

// POST: create a new album. Slug is generated automatically from the title.
export async function POST(req: Request) {
  const admin = await getAdminUser();

  if (!admin) {
    return NextResponse.json(
      { success: false, message: "Unauthorized" },
      { status: 401 }
    );
  }

  try {
    const formData = await req.formData();
    const title = String(formData.get("title") || "").trim();

    if (!title) {
      return NextResponse.json(
        { success: false, message: "Title is required" },
        { status: 400 }
      );
    }

    const slug = await getUniqueAlbumSlug(title);

    let cover = "";
    const coverFile = formData.get("cover");
    if (coverFile && coverFile instanceof File && coverFile.size > 0) {
      cover = await uploadToExternalServer(coverFile, "gallery-albums");
    }

    const last = await prisma.cms_gallery_albums.findFirst({
      orderBy: { sort_order: "desc" },
      select: { sort_order: true },
    });

    const album = await prisma.cms_gallery_albums.create({
      data: {
        title,
        slug,
        cover: cover || null,
        sort_order: (last?.sort_order ?? 0) + 1,
        status: String(formData.get("status") ?? "true") === "true",
      },
    });

    return NextResponse.json({
      success: true,
      data: serializeBigInt(album),
    });
  } catch (error: any) {
    return NextResponse.json(
      { success: false, message: error.message || "Failed to create album" },
      { status: 500 }
    );
  }
}

// PUT: update an album's title, cover, or status.
// Slug stays fixed once created (so existing links never break),
// unless "regenerate_slug" = "true" is explicitly sent.
export async function PUT(req: Request) {
  const admin = await getAdminUser();

  if (!admin) {
    return NextResponse.json(
      { success: false, message: "Unauthorized" },
      { status: 401 }
    );
  }

  try {
    const formData = await req.formData();
    const id = BigInt(String(formData.get("id")));

    const existing = await prisma.cms_gallery_albums.findUnique({
      where: { id },
    });

    if (!existing) {
      return NextResponse.json(
        { success: false, message: "Album not found" },
        { status: 404 }
      );
    }

    const title = formData.has("title")
      ? String(formData.get("title") || "").trim()
      : existing.title;

    let slug = existing.slug;
    if (String(formData.get("regenerate_slug")) === "true") {
      slug = await getUniqueAlbumSlug(title, id);
    }

    let cover = existing.cover;
    const coverFile = formData.get("cover");
    if (coverFile && coverFile instanceof File && coverFile.size > 0) {
      cover = await uploadToExternalServer(coverFile, "gallery-albums");
    }

    const album = await prisma.cms_gallery_albums.update({
      where: { id },
      data: {
        title,
        slug,
        cover,
        status: formData.has("status")
          ? String(formData.get("status")) === "true"
          : existing.status,
        updated_at: new Date(),
      },
    });

    return NextResponse.json({
      success: true,
      data: serializeBigInt(album),
    });
  } catch (error: any) {
    return NextResponse.json(
      { success: false, message: error.message || "Failed to update album" },
      { status: 500 }
    );
  }
}

// DELETE: remove an album and (via cascade) all of its images. Expects ?id=123
export async function DELETE(req: Request) {
  const admin = await getAdminUser();

  if (!admin) {
    return NextResponse.json(
      { success: false, message: "Unauthorized" },
      { status: 401 }
    );
  }

  try {
    const { searchParams } = new URL(req.url);
    const id = searchParams.get("id");

    if (!id) {
      return NextResponse.json(
        { success: false, message: "Missing id" },
        { status: 400 }
      );
    }

    await prisma.cms_gallery_albums.delete({
      where: { id: BigInt(id) },
    });

    return NextResponse.json({ success: true });
  } catch (error: any) {
    return NextResponse.json(
      { success: false, message: error.message || "Failed to delete album" },
      { status: 500 }
    );
  }
}