import { z } from "zod"
import {
  HOSPITALS_PAGE_LOCALE_CODES,
  type HospitalsPageLocaleCode,
} from "@/lib/pages/hospitals-page/locales"
import {
  createEmptyHospitalsPageFormState,
  type HospitalsPageFormStateShape,
} from "@/lib/pages/hospitals-page/form-types"

const HOSPITALS_PAGE_SECTION_KEYS = ["hero", "filters", "accreditation", "why", "faq", "cta"] as const
export type HospitalsPageSectionKey = (typeof HOSPITALS_PAGE_SECTION_KEYS)[number]

function hasAnyMissingStringOrArray(node: unknown, path: string[] = []): boolean {
  const currentKey = path[path.length - 1]
  if (currentKey === "logo") return false

  if (typeof node === "string") return node.trim() === ""
  if (Array.isArray(node)) {
    if (node.length === 0) return true
    return node.some((item, index) => hasAnyMissingStringOrArray(item, [...path, `[${index}]`]))
  }
  if (node && typeof node === "object") {
    return Object.entries(node as Record<string, unknown>).some(([key, value]) =>
      hasAnyMissingStringOrArray(value, [...path, key])
    )
  }
  return false
}

function findFirstMissingPath(node: unknown, path: string[] = []): string | null {
  const currentKey = path[path.length - 1]
  if (currentKey === "logo") return 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({
    icon: z.string(),
    eyebrow: z.string(),
    title: z.string(),
    description: z.string(),
    image: z.string(),
    imagePublicId: z.string(),
    statistics: z.array(
      z.object({
        icon: z.string(),
        title: z.string(),
        subtitle: z.string(),
        value: z.string(),
      })
    ),
    certifications: z.array(
      z.object({
        title: z.string(),
        subtitle: z.string(),
        logo: z.string().optional().default(""),
        image: z.string(),
      })
    ),
  }),
  filters: z.object({
    filters: z.array(
      z.object({
        label: z.string(),
        options: z.array(z.object({ label: z.string() })),
      })
    ),
    sortOptions: z.array(z.object({ label: z.string() })),
  }),
  accreditation: z.object({
    title: z.string(),
    subTitle: z.string(),
    accreditationItems: z.array(
      z.object({
        cardColor: z.string(),
        icon: z.string(),
        title: z.string(),
        subtitle: z.string(),
        description: z.string(),
      })
    ),
  }),
  why: z.object({
    title: z.string(),
    subTitle: z.string(),
    features: z.array(
      z.object({
        icon: z.string(),
        title: z.string(),
        description: z.string(),
      })
    ),
  }),
  faq: z.object({
    title: z.string(),
    faqs: z.array(
      z.object({
        question: z.string(),
        answer: z.string(),
      })
    ),
  }),
  cta: z.object({
    eyebrow: z.string(),
    title: z.string(),
    subtitle: z.string(),
    primaryButtonIcon: z.string(),
    primaryButtonText: z.string(),
    primaryButtonLink: z.string(),
    secondaryButtonIcon: z.string(),
    secondaryButtonText: z.string(),
    secondaryButtonLink: z.string(),
  }),
})

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

export function parseHospitalsPagePutBody(input: unknown):
  | { ok: true; data: { locales: Record<string, HospitalsPageFormStateShape>; sectionKey?: HospitalsPageSectionKey } }
  | { 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: HospitalsPageSectionKey | undefined
  if (typeof raw.sectionKey === "string") {
    if (!HOSPITALS_PAGE_SECTION_KEYS.includes(raw.sectionKey as HospitalsPageSectionKey)) {
      return { ok: false, error: `Unknown section key: ${raw.sectionKey}` }
    }
    sectionKey = raw.sectionKey as HospitalsPageSectionKey
  } 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 (!HOSPITALS_PAGE_LOCALE_CODES.includes(key as HospitalsPageLocaleCode)) {
      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, HospitalsPageFormStateShape>
  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 parseHospitalsPageJsonForStorage(value: unknown): { data: HospitalsPageFormStateShape } {
  const base = createEmptyHospitalsPageFormState()
  const parsed = formStateSchema.safeParse(value)
  return { data: parsed.success ? parsed.data : base }
}
