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.

// TODO: replace with the actual id of the Academy row in cms_pages
const ACADEMY_PAGE_ID = BigInt(3);

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

async function uploadToExternalServer(
  file: File,
  folder: string = "academy"
): Promise<string> {
  try {
    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;
  } catch (error) {
    console.error("External upload error:", error);
    throw error;
  }
}

// GET: fetch the single Academy entry (always scoped to Academy page)
export async function GET() {
  const admin = await getAdminUser();

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

  try {
    const data = await prisma.cms_academy.findUnique({
      where: { page_id: ACADEMY_PAGE_ID },
    });

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

// POST: create the Academy entry (only if one doesn't exist yet)
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 pageExists = await prisma.cms_pages.findUnique({
      where: { id: ACADEMY_PAGE_ID },
    });

    if (!pageExists) {
      return NextResponse.json(
        { success: false, message: "Academy page does not exist in cms_pages" },
        { status: 400 }
      );
    }

    const existing = await prisma.cms_academy.findUnique({
      where: { page_id: ACADEMY_PAGE_ID },
    });

    if (existing) {
      return NextResponse.json(
        {
          success: false,
          message: "An Academy entry already exists. Please edit it instead.",
        },
        { status: 400 }
      );
    }

    // Handle up to 3 separate image uploads
    let remote_classes_image_1 = "";
    let remote_classes_image_2 = "";
    let syllabus_image = "";
    let teaching_image = "";

    const rc1 = formData.get("remote_classes_image_1");
    const rc2 = formData.get("remote_classes_image_2");
    const syl = formData.get("syllabus_image");
    const teach = formData.get("teaching_image");

    if (rc1 && rc1 instanceof File && rc1.size > 0) {
      remote_classes_image_1 = await uploadToExternalServer(rc1, "academy");
    }
    if (rc2 && rc2 instanceof File && rc2.size > 0) {
      remote_classes_image_2 = await uploadToExternalServer(rc2, "academy");
    }
    if (syl && syl instanceof File && syl.size > 0) {
      syllabus_image = await uploadToExternalServer(syl, "academy");
    }
    if (teach && teach instanceof File && teach.size > 0) {
      teaching_image = await uploadToExternalServer(teach, "academy");
    }

    const item = await prisma.cms_academy.create({
      data: {
        page_id: ACADEMY_PAGE_ID,
        remote_classes_heading: String(
          formData.get("remote_classes_heading") || "Remote Classes"
        ),
        remote_classes_content: String(
          formData.get("remote_classes_content") || ""
        ),
        remote_classes_image_1,
        remote_classes_image_2,
        syllabus_heading: String(
          formData.get("syllabus_heading") || "Kuchipudi Syllabus"
        ),
        syllabus_content: String(formData.get("syllabus_content") || ""),
        syllabus_image,
        syllabus_items: String(formData.get("syllabus_items") || ""),
        teaching_heading: String(
          formData.get("teaching_heading") || "Teaching Techniques"
        ),
        teaching_content: String(formData.get("teaching_content") || ""),
        teaching_image,
        status: String(formData.get("status")) === "true",
      },
    });

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

// PUT: update the existing Academy entry
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_academy.findUnique({
      where: { id },
    });

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

    // Keep existing image unless a new file was uploaded
    let remote_classes_image_1 = existing.remote_classes_image_1;
    let remote_classes_image_2 = existing.remote_classes_image_2;
    let syllabus_image = existing.syllabus_image;
    let teaching_image = existing.teaching_image;

    const rc1 = formData.get("remote_classes_image_1");
    const rc2 = formData.get("remote_classes_image_2");
    const syl = formData.get("syllabus_image");
    const teach = formData.get("teaching_image");

    if (rc1 && rc1 instanceof File && rc1.size > 0) {
      remote_classes_image_1 = await uploadToExternalServer(rc1, "academy");
    }
    if (rc2 && rc2 instanceof File && rc2.size > 0) {
      remote_classes_image_2 = await uploadToExternalServer(rc2, "academy");
    }
    if (syl && syl instanceof File && syl.size > 0) {
      syllabus_image = await uploadToExternalServer(syl, "academy");
    }
    if (teach && teach instanceof File && teach.size > 0) {
      teaching_image = await uploadToExternalServer(teach, "academy");
    }

    const item = await prisma.cms_academy.update({
      where: { id },
      data: {
        remote_classes_heading: String(
          formData.get("remote_classes_heading") || "Remote Classes"
        ),
        remote_classes_content: String(
          formData.get("remote_classes_content") || ""
        ),
        remote_classes_image_1,
        remote_classes_image_2,
        syllabus_heading: String(
          formData.get("syllabus_heading") || "Kuchipudi Syllabus"
        ),
        syllabus_content: String(formData.get("syllabus_content") || ""),
        syllabus_image,
        syllabus_items: String(formData.get("syllabus_items") || ""),
        teaching_heading: String(
          formData.get("teaching_heading") || "Teaching Techniques"
        ),
        teaching_content: String(formData.get("teaching_content") || ""),
        teaching_image,
        status: String(formData.get("status")) === "true",
        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 }
    );
  }
}