"use server";

import { revalidatePath } from "next/cache";
import { redirect } from "next/navigation";
import { prisma } from "@/app/lib/db";
import { requireAdmin } from "@/app/actions/auth";
import {
  BlogPostSchema,
  ProgramSchema,
  SubmissionStatusSchema,
  type ActionState,
} from "@/app/lib/definitions";
import {
  deleteUploadedMedia,
  isUploadedMediaUrl,
  saveUploadedImage,
} from "@/app/lib/uploads";

function checkboxValue(formData: FormData, key: string) {
  const value = formData.get(key);
  return value === "on" || value === "true";
}

function getOptionalFile(formData: FormData, key: string) {
  const value = formData.get(key);
  return value instanceof File ? value : null;
}

export async function updateContactStatus(
  id: string,
  formData: FormData,
): Promise<void> {
  await requireAdmin();
  const status = SubmissionStatusSchema.parse(formData.get("status"));
  await prisma.contactSubmission.update({
    where: { id },
    data: { status },
  });
  revalidatePath("/admin");
  revalidatePath("/admin/contacts");
  revalidatePath(`/admin/contacts/${id}`);
}

export async function deleteContact(id: string): Promise<void> {
  await requireAdmin();
  await prisma.contactSubmission.delete({ where: { id } });
  revalidatePath("/admin");
  revalidatePath("/admin/contacts");
  redirect("/admin/contacts");
}

export async function updateAdmissionStatus(
  id: string,
  formData: FormData,
): Promise<void> {
  await requireAdmin();
  const status = SubmissionStatusSchema.parse(formData.get("status"));
  await prisma.admissionSubmission.update({
    where: { id },
    data: { status },
  });
  revalidatePath("/admin");
  revalidatePath("/admin/admissions");
  revalidatePath(`/admin/admissions/${id}`);
}

export async function deleteAdmission(id: string): Promise<void> {
  await requireAdmin();
  await prisma.admissionSubmission.delete({ where: { id } });
  revalidatePath("/admin");
  revalidatePath("/admin/admissions");
  redirect("/admin/admissions");
}

export async function createProgram(
  _prevState: ActionState | undefined,
  formData: FormData,
): Promise<ActionState> {
  await requireAdmin();
  const validated = ProgramSchema.safeParse({
    title: formData.get("title"),
    description: formData.get("description"),
    sortOrder: formData.get("sortOrder") || 0,
    published: checkboxValue(formData, "published"),
  });

  if (!validated.success) {
    return {
      errors: validated.error.flatten().fieldErrors,
      message: "Please fix the highlighted fields.",
    };
  }

  await prisma.program.create({ data: validated.data });
  revalidatePath("/admin/programs");
  revalidatePath("/");
  revalidatePath("/programs");
  redirect("/admin/programs");
}

export async function updateProgram(
  id: string,
  _prevState: ActionState | undefined,
  formData: FormData,
): Promise<ActionState> {
  await requireAdmin();
  const validated = ProgramSchema.safeParse({
    title: formData.get("title"),
    description: formData.get("description"),
    sortOrder: formData.get("sortOrder") || 0,
    published: checkboxValue(formData, "published"),
  });

  if (!validated.success) {
    return {
      errors: validated.error.flatten().fieldErrors,
      message: "Please fix the highlighted fields.",
    };
  }

  await prisma.program.update({ where: { id }, data: validated.data });
  revalidatePath("/admin/programs");
  revalidatePath(`/admin/programs/${id}`);
  revalidatePath("/");
  revalidatePath("/programs");
  redirect("/admin/programs");
}

export async function deleteProgram(id: string): Promise<void> {
  await requireAdmin();
  await prisma.program.delete({ where: { id } });
  revalidatePath("/admin/programs");
  revalidatePath("/");
  revalidatePath("/programs");
  redirect("/admin/programs");
}

export async function createBlogPost(
  _prevState: ActionState | undefined,
  formData: FormData,
): Promise<ActionState> {
  await requireAdmin();
  const validated = BlogPostSchema.safeParse({
    title: formData.get("title"),
    category: formData.get("category"),
    excerpt: formData.get("excerpt"),
    imageUrl: formData.get("imageUrl") ?? "",
    featured: checkboxValue(formData, "featured"),
    sortOrder: formData.get("sortOrder") || 0,
    published: checkboxValue(formData, "published"),
  });

  if (!validated.success) {
    return {
      errors: validated.error.flatten().fieldErrors,
      message: "Please fix the highlighted fields.",
    };
  }

  let imageUrl = validated.data.imageUrl || "";
  try {
    const uploaded = await saveUploadedImage(getOptionalFile(formData, "image"));
    if (uploaded) imageUrl = uploaded.url;
  } catch (error) {
    return {
      message: error instanceof Error ? error.message : "Unable to upload image.",
    };
  }

  await prisma.blogPost.create({
    data: {
      ...validated.data,
      imageUrl,
    },
  });
  revalidatePath("/admin/blogs");
  revalidatePath("/");
  redirect("/admin/blogs");
}

export async function updateBlogPost(
  id: string,
  _prevState: ActionState | undefined,
  formData: FormData,
): Promise<ActionState> {
  await requireAdmin();
  const existing = await prisma.blogPost.findUnique({ where: { id } });
  if (!existing) {
    return { message: "Post not found." };
  }

  const validated = BlogPostSchema.safeParse({
    title: formData.get("title"),
    category: formData.get("category"),
    excerpt: formData.get("excerpt"),
    imageUrl: formData.get("imageUrl") ?? "",
    featured: checkboxValue(formData, "featured"),
    sortOrder: formData.get("sortOrder") || 0,
    published: checkboxValue(formData, "published"),
  });

  if (!validated.success) {
    return {
      errors: validated.error.flatten().fieldErrors,
      message: "Please fix the highlighted fields.",
    };
  }

  let imageUrl = existing.imageUrl || validated.data.imageUrl || "";
  try {
    const uploaded = await saveUploadedImage(getOptionalFile(formData, "image"));
    if (uploaded) imageUrl = uploaded.url;
  } catch (error) {
    return {
      message: error instanceof Error ? error.message : "Unable to upload image.",
    };
  }

  await prisma.blogPost.update({
    where: { id },
    data: {
      ...validated.data,
      imageUrl,
    },
  });

  if (
    existing.imageUrl &&
    isUploadedMediaUrl(existing.imageUrl) &&
    existing.imageUrl !== imageUrl
  ) {
    await deleteUploadedMedia(existing.imageUrl);
  }

  revalidatePath("/admin/blogs");
  revalidatePath(`/admin/blogs/${id}`);
  revalidatePath("/");
  redirect("/admin/blogs");
}

export async function deleteBlogPost(id: string): Promise<void> {
  await requireAdmin();
  const existing = await prisma.blogPost.findUnique({ where: { id } });
  await prisma.blogPost.delete({ where: { id } });
  if (existing?.imageUrl && isUploadedMediaUrl(existing.imageUrl)) {
    await deleteUploadedMedia(existing.imageUrl);
  }
  revalidatePath("/admin/blogs");
  revalidatePath("/");
  redirect("/admin/blogs");
}
