"use server";

import { revalidatePath } from "next/cache";
import { eq } from "drizzle-orm";
import { z } from "zod";
import { db } from "@/lib/db/client";
import { productPages } from "@/lib/db/schema";
import { requireAdmin } from "@/lib/auth/admin-guard";
import { logAdminAction } from "@/lib/audit";
import { PRODUCT_PAGE_SLUGS } from "@/lib/product-pages/defaults";

async function ensureAdmin() {
  const session = await requireAdmin();
  return (session.user as { id?: string }).id!;
}

const featureSchema = z.object({
  title: z.string().trim().max(200).default(""),
  body: z.string().trim().max(1200).default(""),
  iconName: z.string().trim().max(60).default(""),
});

const faqSchema = z.object({
  question: z.string().trim().max(400).default(""),
  answer: z.string().trim().max(2000).default(""),
});

const audienceSchema = z.object({
  title: z.string().trim().max(200).default(""),
  body: z.string().trim().max(1000).default(""),
});

const accessTileSchema = z.object({
  href: z.string().trim().max(300).default(""),
  label: z.string().trim().max(80).default(""),
  description: z.string().trim().max(200).default(""),
  iconName: z.string().trim().max(60).default(""),
});

const customSectionSchema = z.object({
  type: z.enum(["text", "image", "video", "quote"]).default("text"),
  heading: z.string().trim().max(300).default(""),
  body: z.string().trim().max(8000).default(""),
  imagePath: z.string().trim().max(500).default(""),
  imageAlt: z.string().trim().max(500).default(""),
  videoUrl: z.string().trim().max(600).default(""),
  videoProvider: z.string().trim().max(20).default("youtube"),
  ctaLabel: z.string().trim().max(80).default(""),
  ctaHref: z.string().trim().max(300).default(""),
});

function parseJsonArray<T>(raw: unknown, item: z.ZodType<T>): T[] {
  if (typeof raw !== "string" || raw.length === 0) return [];
  let parsed: unknown;
  try {
    parsed = JSON.parse(raw);
  } catch {
    return [];
  }
  const list = z.array(item).safeParse(parsed);
  return list.success ? list.data : [];
}

const updateSchema = z.object({
  slug: z.string().refine((s) => (PRODUCT_PAGE_SLUGS as readonly string[]).includes(s), {
    message: "Unknown product slug",
  }),
  heroEyebrow: z.string().trim().max(120),
  heroTitle: z.string().trim().max(200),
  heroTagline: z.string().trim().max(300),
  heroDescription: z.string().trim().max(2000),
  heroImagePath: z.string().trim().max(500),
  heroImageAlt: z.string().trim().max(500),
  heroPrimaryCtaLabel: z.string().trim().max(80),
  heroPrimaryCtaHref: z.string().trim().max(300),
  heroSecondaryCtaLabel: z.string().trim().max(80),
  heroSecondaryCtaHref: z.string().trim().max(300),
  accessRailTagline: z.string().trim().max(500),
  accessRailMembersOnly: z.string().optional(),
  sectionEyebrow: z.string().trim().max(200),
  sectionHeading: z.string().trim().max(500),
  sectionBody: z.string().trim().max(3000),
  showcaseImagePath: z.string().trim().max(500),
  showcaseImageAlt: z.string().trim().max(500),
  showcaseEyebrow: z.string().trim().max(200),
  showcaseCaption: z.string().trim().max(500),
  audienceHeading: z.string().trim().max(500),
  audienceBody: z.string().trim().max(2000),
  ctaTitle: z.string().trim().max(300),
  ctaBody: z.string().trim().max(1500),
  ctaPrimaryLabel: z.string().trim().max(80),
  ctaPrimaryHref: z.string().trim().max(300),
  ctaSecondaryLabel: z.string().trim().max(80),
  ctaSecondaryHref: z.string().trim().max(300),
});

export async function updateProductPage(formData: FormData) {
  const adminId = await ensureAdmin();

  const parsed = updateSchema.parse({
    slug: formData.get("slug"),
    heroEyebrow: formData.get("heroEyebrow") ?? "",
    heroTitle: formData.get("heroTitle") ?? "",
    heroTagline: formData.get("heroTagline") ?? "",
    heroDescription: formData.get("heroDescription") ?? "",
    heroImagePath: formData.get("heroImagePath") ?? "",
    heroImageAlt: formData.get("heroImageAlt") ?? "",
    heroPrimaryCtaLabel: formData.get("heroPrimaryCtaLabel") ?? "",
    heroPrimaryCtaHref: formData.get("heroPrimaryCtaHref") ?? "",
    heroSecondaryCtaLabel: formData.get("heroSecondaryCtaLabel") ?? "",
    heroSecondaryCtaHref: formData.get("heroSecondaryCtaHref") ?? "",
    accessRailTagline: formData.get("accessRailTagline") ?? "",
    accessRailMembersOnly: (formData.get("accessRailMembersOnly") as string) ?? undefined,
    sectionEyebrow: formData.get("sectionEyebrow") ?? "",
    sectionHeading: formData.get("sectionHeading") ?? "",
    sectionBody: formData.get("sectionBody") ?? "",
    showcaseImagePath: formData.get("showcaseImagePath") ?? "",
    showcaseImageAlt: formData.get("showcaseImageAlt") ?? "",
    showcaseEyebrow: formData.get("showcaseEyebrow") ?? "",
    showcaseCaption: formData.get("showcaseCaption") ?? "",
    audienceHeading: formData.get("audienceHeading") ?? "",
    audienceBody: formData.get("audienceBody") ?? "",
    ctaTitle: formData.get("ctaTitle") ?? "",
    ctaBody: formData.get("ctaBody") ?? "",
    ctaPrimaryLabel: formData.get("ctaPrimaryLabel") ?? "",
    ctaPrimaryHref: formData.get("ctaPrimaryHref") ?? "",
    ctaSecondaryLabel: formData.get("ctaSecondaryLabel") ?? "",
    ctaSecondaryHref: formData.get("ctaSecondaryHref") ?? "",
  });

  const accessTiles = parseJsonArray(formData.get("accessTiles"), accessTileSchema);
  const features = parseJsonArray(formData.get("features"), featureSchema);
  const audiences = parseJsonArray(formData.get("audiences"), audienceSchema);
  const faqs = parseJsonArray(formData.get("faqs"), faqSchema);
  const customSections = parseJsonArray(formData.get("customSections"), customSectionSchema);

  await db
    .update(productPages)
    .set({
      heroEyebrow: parsed.heroEyebrow,
      heroTitle: parsed.heroTitle,
      heroTagline: parsed.heroTagline,
      heroDescription: parsed.heroDescription,
      heroImagePath: parsed.heroImagePath || null,
      heroImageAlt: parsed.heroImageAlt || null,
      heroPrimaryCtaLabel: parsed.heroPrimaryCtaLabel,
      heroPrimaryCtaHref: parsed.heroPrimaryCtaHref,
      heroSecondaryCtaLabel: parsed.heroSecondaryCtaLabel,
      heroSecondaryCtaHref: parsed.heroSecondaryCtaHref,
      accessRailTagline: parsed.accessRailTagline,
      accessRailMembersOnly: parsed.accessRailMembersOnly === "on",
      accessTiles,
      sectionEyebrow: parsed.sectionEyebrow,
      sectionHeading: parsed.sectionHeading,
      sectionBody: parsed.sectionBody,
      showcaseImagePath: parsed.showcaseImagePath || null,
      showcaseImageAlt: parsed.showcaseImageAlt || null,
      showcaseEyebrow: parsed.showcaseEyebrow,
      showcaseCaption: parsed.showcaseCaption,
      features,
      audienceHeading: parsed.audienceHeading,
      audienceBody: parsed.audienceBody,
      audiences,
      faqs,
      ctaTitle: parsed.ctaTitle,
      ctaBody: parsed.ctaBody,
      ctaPrimaryLabel: parsed.ctaPrimaryLabel,
      ctaPrimaryHref: parsed.ctaPrimaryHref,
      ctaSecondaryLabel: parsed.ctaSecondaryLabel,
      ctaSecondaryHref: parsed.ctaSecondaryHref,
      customSections,
      updatedAt: new Date(),
      updatedBy: adminId,
    })
    .where(eq(productPages.slug, parsed.slug));

  await logAdminAction({
    adminUserId: adminId,
    action: "update_product_page",
    metadata: { slug: parsed.slug },
  });

  revalidatePath("/admin/product-pages");
  revalidatePath(`/admin/product-pages/${parsed.slug}`);
  revalidatePath(`/products/${parsed.slug}`);
}

const resetSchema = z.object({
  slug: z.string().refine((s) => (PRODUCT_PAGE_SLUGS as readonly string[]).includes(s)),
});

export async function resetProductPageToDefaults(formData: FormData) {
  const adminId = await ensureAdmin();
  const { slug } = resetSchema.parse({ slug: formData.get("slug") });

  const { getDefaults } = await import("@/lib/product-pages/defaults");
  const defaults = getDefaults(slug);
  if (!defaults) return;

  await db
    .update(productPages)
    .set({
      ...defaults,
      updatedAt: new Date(),
      updatedBy: adminId,
    })
    .where(eq(productPages.slug, slug));

  await logAdminAction({
    adminUserId: adminId,
    action: "reset_product_page",
    metadata: { slug },
  });

  revalidatePath("/admin/product-pages");
  revalidatePath(`/admin/product-pages/${slug}`);
  revalidatePath(`/products/${slug}`);
}
