import { prisma } from "@/lib/prisma";
import { getAdminUser } from "@/lib/auth";
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;
}

interface RouteParams {
  params: Promise<{ albumId: string }>;
}

// GET: list all images for an album (admin view -> includes inactive)
export async function GET(_req: Request, { params }: RouteParams) {
  const admin = await getAdminUser();

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

  try {
    const { albumId } = await params;

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

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

    const images = await prisma.cms_gallery_album_images.findMany({
      where: { album_id: BigInt(albumId) },
      orderBy: { sort_order: "asc" },
    });

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

// POST: upload one or more images into this album.
// Send files under the key "images" (append multiple times).
export async function POST(req: Request, { params }: RouteParams) {
  const admin = await getAdminUser();

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

  try {
    const { albumId } = await params;
    const album_id = BigInt(albumId);

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

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

    const formData = await req.formData();
    const files = formData
      .getAll("images")
      .filter((f): f is File => f instanceof File && f.size > 0);

    if (files.length === 0) {
      return NextResponse.json(
        { success: false, message: "No image files provided" },
        { status: 400 }
      );
    }

    const last = await prisma.cms_gallery_album_images.findFirst({
      where: { album_id },
      orderBy: { sort_order: "desc" },
      select: { sort_order: true },
    });
    let nextSortOrder = (last?.sort_order ?? 0) + 1;

    const created = [];

    for (const file of files) {
      const url = await uploadToExternalServer(file, "gallery-albums");

      const item = await prisma.cms_gallery_album_images.create({
        data: {
          album_id,
          image: url,
          sort_order: nextSortOrder,
          status: true,
        },
      });

      created.push(item);
      nextSortOrder++;
    }

    // If the album has no cover yet, use the first uploaded image as cover
    if (!album.cover && created.length > 0) {
      await prisma.cms_gallery_albums.update({
        where: { id: album_id },
        data: { cover: created[0].image },
      });
    }

    return NextResponse.json({
      success: true,
      data: serializeBigInt(created),
    });
  } catch (error: any) {
    console.error("Album image upload error:", error);
    return NextResponse.json(
      { success: false, message: error.message || "Failed to upload images" },
      { status: 500 }
    );
  }
}

// PUT: update a single image (caption, status, or replace the file)
export async function PUT(req: Request, { params }: RouteParams) {
  const admin = await getAdminUser();

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

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

    const existing = await prisma.cms_gallery_album_images.findFirst({
      where: { id, album_id: BigInt(albumId) },
    });

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

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

    const item = await prisma.cms_gallery_album_images.update({
      where: { id },
      data: {
        image,
        caption: formData.has("caption")
          ? String(formData.get("caption") || "")
          : existing.caption,
        status: formData.has("status")
          ? String(formData.get("status")) === "true"
          : existing.status,
        updated_at: new Date(),
      },
    });

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

// DELETE: remove an image from the album. Expects ?id=123
export async function DELETE(req: Request, { params }: RouteParams) {
  const admin = await getAdminUser();

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

  try {
    const { albumId } = await params;
    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_album_images.deleteMany({
      where: { id: BigInt(id), album_id: BigInt(albumId) },
    });

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