import { z } from "zod"
import type { BlogHeroSectionData, BlogImageStat, BlogQuickStat } from "@/components/dashboard/blog/BlogHeroSection"
import { BLOG_PAGE_LOCALE_CODES, type BlogPageLocaleCode } from "@/lib/pages/blog/locales"
import { createEmptyBlogPageFormState } from "@/lib/pages/blog/form-types"

const blogQuickStatSchema = z.object({
  label: z.string(),
  icon: z.string(),
})

const blogImageStatSchema = z.object({
  icon: z.string(),
  label: z.string(),
  value: z.string(),
})

export const blogHeroSectionDataSchema = z.object({
  eyebrow: z.string(),
  title: z.string(),
  description: z.string(),
  quickStats: z.array(blogQuickStatSchema),
  image: z.string(),
  imagePublicId: z.string().optional().default(""),
  imageStats: blogImageStatSchema,
})

function strField(o: Record<string, unknown>, key: string, fallback: string): string {
  return typeof o[key] === "string" ? (o[key] as string) : fallback
}

function isQuickStat(x: unknown): x is BlogQuickStat {
  if (!x || typeof x !== "object") return false
  const r = x as { label?: unknown; icon?: unknown }
  return typeof r.label === "string" && typeof r.icon === "string"
}

function isImageStats(x: unknown): x is BlogImageStat {
  if (!x || typeof x !== "object") return false
  const r = x as { icon?: unknown; label?: unknown; value?: unknown }
  return (
    typeof r.icon === "string" &&
    typeof r.label === "string" &&
    typeof r.value === "string"
  )
}

/**
 * Merges partial / legacy / minimal `{ title, description, image }` shapes into a full hero object.
 * Unknown fields are ignored; missing optional sections use empty defaults.
 */
export function normalizeBlogHeroFromJson(value: unknown): BlogHeroSectionData {
  const base = createEmptyBlogPageFormState().hero
  if (value == null || typeof value !== "object" || Array.isArray(value)) {
    return base
  }
  const o = value as Record<string, unknown>
  const quickStats: BlogQuickStat[] = Array.isArray(o.quickStats)
    ? (o.quickStats as unknown[]).filter(isQuickStat)
    : base.quickStats
  const imageStats: BlogImageStat = isImageStats(o.imageStats)
    ? o.imageStats
    : base.imageStats
  return {
    eyebrow: strField(o, "eyebrow", base.eyebrow),
    title: strField(o, "title", base.title),
    description: strField(o, "description", base.description),
    quickStats,
    image: strField(o, "image", base.image),
    imagePublicId: strField(o, "imagePublicId", base.imagePublicId),
    imageStats,
  }
}

const blogPageFormStateSchema = z.object({
  hero: blogHeroSectionDataSchema,
})

const localesInputSchema = z
  .record(z.string(), blogPageFormStateSchema)
  .superRefine((val, ctx) => {
    const en = val.en
    if (!en) {
      ctx.addIssue({ code: z.ZodIssueCode.custom, message: "English (en) content is required", path: ["en"] })
      return
    }
    if (!en.hero.title.trim()) {
      ctx.addIssue({ code: z.ZodIssueCode.custom, message: "English title is required", path: ["en", "hero", "title"] })
    }
    if (!en.hero.description.trim()) {
      ctx.addIssue({ code: z.ZodIssueCode.custom, message: "English description is required", path: ["en", "hero", "description"] })
    }
  })

const putBodySchema = z.object({
  locales: localesInputSchema,
})

export function parseBlogPagePutBody(input: unknown):
  | { ok: true; data: { locales: Record<string, { hero: z.infer<typeof blogHeroSectionDataSchema> }> } }
  | { ok: false; error: string } {
  // Filter to supported locale codes only (extensible: add new codes in blog-page-locales.ts)
  if (!input || typeof input !== "object" || !("locales" in input)) {
    return { ok: false, error: "Invalid body: expected { locales }" }
  }
  const raw = input as { locales: unknown }
  if (!raw.locales || typeof raw.locales !== "object" || Array.isArray(raw.locales)) {
    return { ok: false, error: "Invalid locales" }
  }

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

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

  return { ok: true, data: parsed.data }
}

export function parseHeroJsonForStorage(value: unknown): { data: z.infer<typeof blogHeroSectionDataSchema> } {
  const data = normalizeBlogHeroFromJson(value)
  const r = blogHeroSectionDataSchema.safeParse(data)
  return { data: r.success ? r.data : data }
}
