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 = "moment"
): 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_moment_badges.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, "moment");
    }

    const item = await prisma.cms_moment_badges.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_moment_badges.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, "moment");
    }

    const item = await prisma.cms_moment_badges.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_moment_badges.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,
      }
    );
  }
}