"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 {
  AboutSettingsSchema,
  BlogsSectionSettingsSchema,
  FooterSettingsSchema,
  GedSettingsSchema,
  HeaderSettingsSchema,
  HeroSettingsSchema,
  HomepageItemSchema,
  PartnersSectionSettingsSchema,
  ProgramsSectionSettingsSchema,
  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;
}

async function upsertSettings(entries: Record<string, string>) {
  for (const [key, value] of Object.entries(entries)) {
    await prisma.siteSetting.upsert({
      where: { key },
      update: { value },
      create: { key, value },
    });
  }
}

async function replaceSettingImage(
  key: string,
  file: File | null,
  currentValue?: string,
) {
  if (!file || file.size === 0) return currentValue ?? "";
  const uploaded = await saveUploadedImage(file);
  if (!uploaded) return currentValue ?? "";

  const previous = currentValue ?? (await prisma.siteSetting.findUnique({ where: { key } }))?.value;
  await upsertSettings({ [key]: uploaded.url });
  if (previous && isUploadedMediaUrl(previous) && previous !== uploaded.url) {
    await deleteUploadedMedia(previous);
  }
  return uploaded.url;
}

function revalidateHomepageAdmin(paths: string[] = []) {
  revalidatePath("/");
  revalidatePath("/admin/homepage");
  for (const path of paths) {
    revalidatePath(path);
  }
}

export async function updateHomepageSections(
  _prevState: ActionState | undefined,
  formData: FormData,
): Promise<ActionState> {
  await requireAdmin();
  const sections = await prisma.homepageSection.findMany({
    orderBy: { sortOrder: "asc" },
  });

  for (const section of sections) {
    const sortOrder = Number(formData.get(`sortOrder_${section.key}`) ?? section.sortOrder);
    const visible = checkboxValue(formData, `visible_${section.key}`);
    await prisma.homepageSection.update({
      where: { id: section.id },
      data: {
        sortOrder: Number.isFinite(sortOrder) ? sortOrder : section.sortOrder,
        visible,
      },
    });
  }

  revalidateHomepageAdmin();
  return { success: true, message: "Section order and visibility saved." };
}

export async function updateHeaderSettings(
  _prevState: ActionState | undefined,
  formData: FormData,
): Promise<ActionState> {
  await requireAdmin();
  const validated = HeaderSettingsSchema.safeParse({
    header_title: formData.get("header_title"),
    header_subtitle: formData.get("header_subtitle"),
  });

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

  try {
    await upsertSettings(validated.data);
    const current = await prisma.siteSetting.findUnique({
      where: { key: "header_logo" },
    });
    await replaceSettingImage(
      "header_logo",
      getOptionalFile(formData, "header_logo"),
      current?.value,
    );
  } catch (error) {
    return {
      message:
        error instanceof Error ? error.message : "Unable to save header settings.",
    };
  }

  revalidateHomepageAdmin(["/admin/homepage/header"]);
  return { success: true, message: "Header settings saved." };
}

export async function updateHeroSettings(
  _prevState: ActionState | undefined,
  formData: FormData,
): Promise<ActionState> {
  await requireAdmin();
  const validated = HeroSettingsSchema.safeParse({
    hero_heading: formData.get("hero_heading"),
    hero_description: formData.get("hero_description"),
    hero_cta_text: formData.get("hero_cta_text"),
    hero_cta_href: formData.get("hero_cta_href"),
  });

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

  await upsertSettings(validated.data);
  revalidateHomepageAdmin(["/admin/homepage/hero", "/admin/settings"]);
  return { success: true, message: "Hero settings saved." };
}

export async function updateGedSettings(
  _prevState: ActionState | undefined,
  formData: FormData,
): Promise<ActionState> {
  await requireAdmin();
  const validated = GedSettingsSchema.safeParse({
    ged_heading: formData.get("ged_heading"),
    ged_body: formData.get("ged_body"),
    ged_seal_top: formData.get("ged_seal_top"),
    ged_seal_main: formData.get("ged_seal_main"),
    ged_seal_bottom: formData.get("ged_seal_bottom"),
  });

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

  await upsertSettings(validated.data);
  revalidateHomepageAdmin(["/admin/homepage/ged"]);
  return { success: true, message: "GED section saved." };
}

export async function updateAboutSettings(
  _prevState: ActionState | undefined,
  formData: FormData,
): Promise<ActionState> {
  await requireAdmin();
  const validated = AboutSettingsSchema.safeParse({
    about_heading: formData.get("about_heading"),
    about_body: formData.get("about_body"),
    about_cta_text: formData.get("about_cta_text"),
    about_cta_href: formData.get("about_cta_href"),
  });

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

  try {
    await upsertSettings(validated.data);
    const current = await prisma.siteSetting.findMany({
      where: {
        key: { in: ["about_image_primary", "about_image_secondary"] },
      },
    });
    const map = Object.fromEntries(current.map((row) => [row.key, row.value]));
    await replaceSettingImage(
      "about_image_primary",
      getOptionalFile(formData, "about_image_primary"),
      map.about_image_primary,
    );
    await replaceSettingImage(
      "about_image_secondary",
      getOptionalFile(formData, "about_image_secondary"),
      map.about_image_secondary,
    );
  } catch (error) {
    return {
      message:
        error instanceof Error ? error.message : "Unable to save about section.",
    };
  }

  revalidateHomepageAdmin(["/admin/homepage/about"]);
  return { success: true, message: "About section saved." };
}

export async function updateProgramsSectionSettings(
  _prevState: ActionState | undefined,
  formData: FormData,
): Promise<ActionState> {
  await requireAdmin();
  const validated = ProgramsSectionSettingsSchema.safeParse({
    programs_heading: formData.get("programs_heading"),
    programs_body: formData.get("programs_body"),
  });

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

  try {
    await upsertSettings(validated.data);
    const current = await prisma.siteSetting.findUnique({
      where: { key: "programs_image" },
    });
    await replaceSettingImage(
      "programs_image",
      getOptionalFile(formData, "programs_image"),
      current?.value,
    );
  } catch (error) {
    return {
      message:
        error instanceof Error
          ? error.message
          : "Unable to save programs section.",
    };
  }

  revalidateHomepageAdmin(["/admin/homepage/programs"]);
  return { success: true, message: "Programs section saved." };
}

export async function updatePartnersSectionSettings(
  _prevState: ActionState | undefined,
  formData: FormData,
): Promise<ActionState> {
  await requireAdmin();
  const validated = PartnersSectionSettingsSchema.safeParse({
    partners_label: formData.get("partners_label"),
  });

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

  await upsertSettings(validated.data);
  revalidateHomepageAdmin(["/admin/homepage/partners"]);
  return { success: true, message: "Partners section saved." };
}

export async function updateBlogsSectionSettings(
  _prevState: ActionState | undefined,
  formData: FormData,
): Promise<ActionState> {
  await requireAdmin();
  const validated = BlogsSectionSettingsSchema.safeParse({
    blogs_heading: formData.get("blogs_heading"),
    blogs_body: formData.get("blogs_body"),
  });

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

  await upsertSettings(validated.data);
  revalidateHomepageAdmin(["/admin/homepage/blogs"]);
  return { success: true, message: "Blog section saved." };
}

export async function updateFooterSettings(
  _prevState: ActionState | undefined,
  formData: FormData,
): Promise<ActionState> {
  await requireAdmin();
  const validated = FooterSettingsSchema.safeParse({
    footer_title: formData.get("footer_title"),
    footer_description: formData.get("footer_description"),
    footer_address: formData.get("footer_address"),
    footer_phone: formData.get("footer_phone"),
    footer_email: formData.get("footer_email"),
    footer_programs_heading: formData.get("footer_programs_heading"),
    footer_contact_heading: formData.get("footer_contact_heading"),
  });

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

  await upsertSettings(validated.data);
  revalidateHomepageAdmin(["/admin/homepage/footer"]);
  return { success: true, message: "Footer settings saved." };
}

export async function createHomepageItem(
  section: string,
  _prevState: ActionState | undefined,
  formData: FormData,
): Promise<ActionState> {
  await requireAdmin();
  const validated = HomepageItemSchema.safeParse({
    label: formData.get("label"),
    text: formData.get("text") ?? "",
    href: formData.get("href") ?? "",
    altText: formData.get("altText") ?? "",
    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 = "";
  try {
    const uploaded = await saveUploadedImage(getOptionalFile(formData, "image"));
    imageUrl = uploaded?.url ?? String(formData.get("imageUrl") ?? "");
  } catch (error) {
    return {
      message: error instanceof Error ? error.message : "Unable to upload image.",
    };
  }

  await prisma.homepageItem.create({
    data: {
      section,
      ...validated.data,
      text: validated.data.text || "",
      href: validated.data.href || "",
      altText: validated.data.altText || "",
      imageUrl,
    },
  });

  revalidateHomepageAdmin([`/admin/homepage/${sectionPath(section)}`]);
  redirect(`/admin/homepage/${sectionPath(section)}`);
}

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

  const validated = HomepageItemSchema.safeParse({
    label: formData.get("label"),
    text: formData.get("text") ?? "",
    href: formData.get("href") ?? "",
    altText: formData.get("altText") ?? "",
    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;
  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.homepageItem.update({
    where: { id },
    data: {
      ...validated.data,
      text: validated.data.text || "",
      href: validated.data.href || "",
      altText: validated.data.altText || "",
      imageUrl,
    },
  });

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

  revalidateHomepageAdmin([`/admin/homepage/${sectionPath(section)}`]);
  redirect(`/admin/homepage/${sectionPath(section)}`);
}

export async function deleteHomepageItem(
  id: string,
  section: string,
): Promise<void> {
  await requireAdmin();
  const existing = await prisma.homepageItem.findUnique({ where: { id } });
  if (!existing) {
    redirect(`/admin/homepage/${sectionPath(section)}`);
  }

  await prisma.homepageItem.delete({ where: { id } });
  if (existing.imageUrl && isUploadedMediaUrl(existing.imageUrl)) {
    await deleteUploadedMedia(existing.imageUrl);
  }

  revalidateHomepageAdmin([`/admin/homepage/${sectionPath(section)}`]);
  redirect(`/admin/homepage/${sectionPath(section)}`);
}

function sectionPath(section: string) {
  switch (section) {
    case "hero_slide":
      return "hero";
    case "partner":
      return "partners";
    case "footer_program":
      return "footer";
    default:
      return section;
  }
}
