import { z } from "zod"
import { createEmptyProceduresPageFormState, type ProceduresPageFormStateShape } from "@/lib/pages/procedures-page/form-types"
import { PROCEDURES_PAGE_LOCALE_CODES, type ProceduresPageLocaleCode } from "@/lib/pages/procedures-page/locales"

const PROCEDURES_PAGE_SECTION_KEYS = [
  "hero",
  "filters",
  "stats",
  "comparison",
  "whyTurkey",
  "faq",
  "quickLinks",
  "finalCta",
] as const
export type ProceduresPageSectionKey = (typeof PROCEDURES_PAGE_SECTION_KEYS)[number]

function hasAnyMissingStringOrArray(node: unknown): boolean {
  if (typeof node === "string") return node.trim() === ""
  if (Array.isArray(node)) {
    if (node.length === 0) return true
    return node.some((item) => hasAnyMissingStringOrArray(item))
  }
  if (node && typeof node === "object") {
    return Object.values(node as Record<string, unknown>).some((value) => hasAnyMissingStringOrArray(value))
  }
  return false
}

function findFirstMissingPath(node: unknown, path: string[] = []): string | null {
  if (typeof node === "string") return node.trim() === "" ? path.join(".") || "en" : null
  if (Array.isArray(node)) {
    if (node.length === 0) return path.join(".") || "en"
    for (let index = 0; index < node.length; index += 1) {
      const missingPath = findFirstMissingPath(node[index], [...path, `[${index}]`])
      if (missingPath) return missingPath
    }
    return null
  }
  if (node && typeof node === "object") {
    for (const [key, value] of Object.entries(node as Record<string, unknown>)) {
      const missingPath = findFirstMissingPath(value, [...path, key])
      if (missingPath) return missingPath
    }
  }
  return null
}

const formStateSchema = z.object({
  hero: z.object({
    title: z.string(),
    description: z.string(),
    image: z.string(),
    imagePublicId: z.string(),
    categories: z.array(z.object({ icon: z.string(), name: z.string() })),
  }),
  filters: z.object({
    filters: z.array(z.object({ label: z.string(), options: z.array(z.object({ label: z.string() })) })),
    mainFilterOptionsTitle: z.string(),
    mainFilterOptions: z.array(z.object({ label: z.string() })),
  }),
  stats: z.object({
    stats: z.array(z.object({ label: z.string(), value: z.string() })),
  }),
  comparison: z.object({
    eyebrow: z.string(),
    title: z.string(),
    subtitle: z.string(),
  }),
  whyTurkey: z.object({
    eyebrow: z.string(),
    title: z.string(),
    features: z.array(
      z.object({
        cardColor: z.string(),
        icon: z.string(),
        title: z.string(),
        description: z.string(),
        label: z.string(),
        value: z.string(),
      })
    ),
  }),
  faq: z.object({
    eyebrow: z.string(),
    title: z.string(),
    faqs: z.array(z.object({ question: z.string(), answer: z.string() })),
  }),
  quickLinks: z.object({
    links: z.array(z.object({ icon: z.string(), title: z.string(), subtitle: z.string(), link: z.string() })),
  }),
  finalCta: z.object({
    eyebrow: z.string(),
    title: z.string(),
    subtitle: z.string(),
    buttonIcon: z.string(),
    buttonText: z.string(),
    buttonLink: z.string(),
  }),
})

const localesSchema = z.record(z.string(), formStateSchema)

export function parseProceduresPagePutBody(input: unknown):
  | { ok: true; data: { locales: Record<string, ProceduresPageFormStateShape>; sectionKey?: ProceduresPageSectionKey } }
  | { ok: false; error: string } {
  if (!input || typeof input !== "object" || !("locales" in input)) {
    return { ok: false, error: "Invalid body: expected { locales }" }
  }
  const raw = input as { locales: unknown; sectionKey?: unknown }
  if (!raw.locales || typeof raw.locales !== "object" || Array.isArray(raw.locales)) {
    return { ok: false, error: "Invalid locales" }
  }

  let sectionKey: ProceduresPageSectionKey | undefined
  if (typeof raw.sectionKey === "string") {
    if (!PROCEDURES_PAGE_SECTION_KEYS.includes(raw.sectionKey as ProceduresPageSectionKey)) {
      return { ok: false, error: `Unknown section key: ${raw.sectionKey}` }
    }
    sectionKey = raw.sectionKey as ProceduresPageSectionKey
  } else if (raw.sectionKey !== undefined) {
    return { ok: false, error: "Invalid section key" }
  }

  for (const key of Object.keys(raw.locales as Record<string, unknown>)) {
    if (!PROCEDURES_PAGE_LOCALE_CODES.includes(key as ProceduresPageLocaleCode)) {
      return { ok: false, error: `Unknown locale: ${key}` }
    }
  }

  const parsed = z.object({ locales: localesSchema }).safeParse({ locales: raw.locales })
  if (!parsed.success) return { ok: false, error: parsed.error.issues[0]?.message ?? "Validation failed" }

  const parsedLocales = parsed.data.locales as Record<string, ProceduresPageFormStateShape>
  const englishLocale = parsedLocales.en
  if (!englishLocale) return { ok: false, error: "English (en) content is required" }

  if (sectionKey) {
    const englishSection = englishLocale[sectionKey]
    if (hasAnyMissingStringOrArray(englishSection)) {
      const missingPath = findFirstMissingPath(englishSection, ["en", sectionKey])
      return { ok: false, error: missingPath ? `Please fill all required English fields. Missing: ${missingPath}` : "Please fill all required English fields." }
    }
  } else if (hasAnyMissingStringOrArray(englishLocale)) {
    const missingPath = findFirstMissingPath(englishLocale)
    return { ok: false, error: missingPath ? `Please fill all required English fields. Missing: ${missingPath}` : "Please fill all required English fields." }
  }

  return { ok: true, data: { locales: parsedLocales, sectionKey } }
}

export function parseProceduresPageJsonForStorage(value: unknown): { data: ProceduresPageFormStateShape } {
  const base = createEmptyProceduresPageFormState()
  const parsed = formStateSchema.safeParse(value)
  return { data: parsed.success ? parsed.data : base }
}
