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";

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

async function uploadToExternalServer(
  file: File,
  folder: string = "online-classes"
): 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;
  }
}

export async function GET(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 pageIdParam = searchParams.get("page_id");

    const page_id = pageIdParam ? BigInt(pageIdParam) : BigInt(1);

    const data = await prisma.cms_online_classes.findMany({
      where: { page_id },
      orderBy: { sort_order: "asc" },
    });

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

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 page_id = formData.get("page_id")
      ? BigInt(String(formData.get("page_id")))
      : BigInt(1);

    const pageExists = await prisma.cms_pages.findUnique({
      where: { id: page_id },
    });

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

    let image = "";

    const imageFile = formData.get("image");

    if (imageFile && imageFile instanceof File && imageFile.size > 0) {
      image = await uploadToExternalServer(imageFile, "online-classes");
    }

    const item = await prisma.cms_online_classes.create({
      data: {
        page_id,
        title,
        image,
        sort_order: Number(formData.get("sort_order") || 0),
        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 }
    );
  }
}

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_online_classes.findUnique({
      where: { id },
    });

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

    const title = String(formData.get("title") || "").trim();

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

    const page_id = formData.get("page_id")
      ? BigInt(String(formData.get("page_id")))
      : existing.page_id;

    if (page_id !== existing.page_id) {
      const pageExists = await prisma.cms_pages.findUnique({
        where: { id: page_id },
      });

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

    let image = existing.image;

    const imageFile = formData.get("image");

    if (imageFile && imageFile instanceof File && imageFile.size > 0) {
      image = await uploadToExternalServer(imageFile, "online-classes");
    }

    const item = await prisma.cms_online_classes.update({
      where: { id },
      data: {
        page_id,
        title,
        image,
        sort_order: Number(formData.get("sort_order") || 0),
        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 }
    );
  }
}

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 = BigInt(searchParams.get("id") || "0");

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

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