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"
): 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: fetch all gallery images (admin view -> includes inactive), ordered by sort_order
export async function GET() {
  const admin = await getAdminUser();

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

  try {
    const images = await prisma.cms_gallery_images.findMany({
      orderBy: { sort_order: "asc" },
    });

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

// POST: upload and create one or more gallery images in a single request.
// Send files under the key "images" (can append multiple times).
// Optional: "captions" as a JSON-stringified array aligned by index.
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 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 }
      );
    }

    let captions: string[] = [];
    const captionsRaw = formData.get("captions");
    if (captionsRaw) {
      try {
        captions = JSON.parse(String(captionsRaw));
      } catch {
        captions = [];
      }
    }

    // Base sort_order off current max so new images append at the end
    const last = await prisma.cms_gallery_images.findFirst({
      orderBy: { sort_order: "desc" },
      select: { sort_order: true },
    });
    let nextSortOrder = (last?.sort_order ?? 0) + 1;

    const created = [];

    for (let i = 0; i < files.length; i++) {
      const url = await uploadToExternalServer(files[i], "gallery");

      const item = await prisma.cms_gallery_images.create({
        data: {
          image: url,
          caption: captions[i] || null,
          sort_order: nextSortOrder,
          status: true,
        },
      });

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

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

// PUT: update an existing image entry (caption, sort_order, status, or replace the image file)
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_images.findUnique({
      where: { id },
    });

    if (!existing) {
      return NextResponse.json(
        { success: false, message: "Record 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");
    }

    const item = await prisma.cms_gallery_images.update({
      where: { id },
      data: {
        image,
        caption: formData.has("caption")
          ? String(formData.get("caption") || "")
          : existing.caption,
        sort_order: formData.has("sort_order")
          ? Number(formData.get("sort_order"))
          : existing.sort_order,
        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 record" },
      { status: 500 }
    );
  }
}

// DELETE: remove a gallery image (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_images.delete({
      where: { id: BigInt(id) },
    });

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