﻿import { extractMediaKeyFromUrl } from "@/lib/r2-storage"

export const HOSPITAL_LOCALES = ["en", "ar", "tr"] as const
export type HospitalLocale = (typeof HOSPITAL_LOCALES)[number]

type JsonRecord = Record<string, unknown>

export function parseHospitalLocale(value: unknown): HospitalLocale {
  if (value === "ar" || value === "tr") return value
  return "en"
}

export function parseHospitalStoredJson<T>(value: unknown, fallback: T): T {
  if (typeof value !== "string") return fallback
  try {
    return JSON.parse(value) as T
  } catch {
    return fallback
  }
}

export function serializeHospitalJson(value: unknown): string {
  return JSON.stringify(value ?? {})
}

/** Keep each locale payload as submitted — no copying images or strings from English into other locales. */
export function normalizeHospitalSharedImages(translations: JsonRecord): JsonRecord {
  const next: JsonRecord = {}
  for (const locale of HOSPITAL_LOCALES) {
    const raw = translations[locale]
    next[locale] = raw && typeof raw === "object" ? ({ ...(raw as JsonRecord) }) : {}
  }
  return next
}

/** Dashboard form slice for ar/tr when no `HospitalTranslation` row exists (no fallback to English in the editor). */
export function emptyHospitalLocaleFormFields(): Record<string, unknown> {
  return {
    hospitalName: "",
    hospitalLocation: "",
    hospitalType: "",
    hero: { virtualTourUrl: "", heroStats: [], galleryImages: [] },
    about: { eyebrow: "", title: "", description: "", aboutStats: [] },
    gallery: { eyebrow: "", title: "", categories: [], images: [], videos: [] },
    departments: { eyebrow: "", title: "", subtitle: "", departments: [] },
    doctors: { eyebrow: "", title: "", primaryButtonText: "", primaryButtonLink: "", doctorIds: [] },
    accreditation: { eyebrow: "", title: "", subtitle: "", accreditations: [] },
    technology: { eyebrow: "", title: "", subtitle: "", technologies: [] },
    visitProcess: { eyebrow: "", title: "", subtitle: "", steps: [] },
    reviews: { eyebrow: "", title: "", reviews: [] },
    location: {
      eyebrow: "",
      title: "",
      googleMapsUrl: "",
      contactInfoCardTitle: "",
      contactInfo: [],
      contactButtonIcon: "",
      contactButtonText: "",
      contactButtonLink: "",
      extraCardTitle: "",
      extraCard: [],
    },
    packages: { eyebrow: "", title: "", subtitle: "" },
    faq: { eyebrow: "", title: "", faqs: [] },
    cta: {
      eyebrow: "",
      title: "",
      subtitle: "",
      features: [],
      buttonIcon: "",
      buttonText: "",
      buttonLink: "",
      formTitle: "",
      fullNameLabel: "",
      phoneLabel: "",
      emailLabel: "",
      procedureLabel: "",
      procedures: [],
      messageLabel: "",
      formButtonIcon: "",
      formButtonText: "",
      formButtonLink: "",
      endOfFormLabel: "",
    },
    similar: { eyebrow: "", title: "", primaryButtonText: "", primaryButtonLink: "" },
  }
}

export function collectMissingEnglishFields(value: unknown): string[] {
  const missing: string[] = []
  walkMissingFields(value, "en", missing)
  return missing
}

function walkMissingFields(value: unknown, path: string, missing: string[]) {
  if (typeof value === "string") {
    if (value.trim() === "") missing.push(path)
    return
  }
  if (typeof value === "number" || typeof value === "boolean") return
  if (value === null || value === undefined) {
    missing.push(path)
    return
  }
  if (Array.isArray(value)) {
    if (value.length === 0) {
      missing.push(path)
      return
    }
    value.forEach((item, idx) => walkMissingFields(item, `${path}[${idx}]`, missing))
    return
  }
  if (typeof value === "object") {
    const record = value as JsonRecord
    for (const key of Object.keys(record)) {
      if (shouldSkipValidationPath(key)) continue
      walkMissingFields(record[key], `${path}.${key}`, missing)
    }
  }
}

function shouldSkipValidationPath(key: string): boolean {
  const lower = key.toLowerCase()
  if (lower.includes("publicid")) return true
  /** Deprecated UI field — persisted empty; not required for publish */
  if (key === "heroStats") return true
  return false
}

export function toHospitalFolderSegment(value: string): string {
  const normalized = value
    .trim()
    .toLowerCase()
    .replace(/[^a-z0-9\s-_]/g, "")
    .replace(/\s+/g, "-")
    .replace(/-+/g, "-")
    .replace(/^[-_]+|[-_]+$/g, "")
  return normalized || "untitled-hospital"
}

export function resolveHospitalImageFolder(input: { slug?: string; name?: string }) {
  const slug = typeof input.slug === "string" ? input.slug.trim() : ""
  const name = typeof input.name === "string" ? input.name.trim() : ""
  const segment = slug || toHospitalFolderSegment(name)
  return `hospitals/${segment}`
}

/** R2 prefix root for a hospital slug: `hospitals/{slug-segment}`. */
export function hospitalMediaBaseForSlug(slug: string): string {
  return `hospitals/${toHospitalFolderSegment(slug)}`
}

/** Rewrite stored media keys and public URLs after a slug change. */
export function rewriteHospitalMediaPaths(
  value: unknown,
  oldBase: string,
  newBase: string
): unknown {
  if (oldBase === newBase) return value
  if (value === null || value === undefined) return value
  if (typeof value === "string") {
    if (!value.includes(oldBase)) return value
    return value.split(oldBase).join(newBase)
  }
  if (Array.isArray(value)) {
    return value.map((item) => rewriteHospitalMediaPaths(item, oldBase, newBase))
  }
  if (typeof value === "object") {
    const record = value as JsonRecord
    const out: JsonRecord = {}
    for (const [key, raw] of Object.entries(record)) {
      out[key] = rewriteHospitalMediaPaths(raw, oldBase, newBase)
    }
    return out
  }
  return value
}

export function folderFromMediaKey(mediaKey: string): string | null {
  const id = mediaKey.trim()
  const idx = id.lastIndexOf("/")
  if (idx <= 0) return null
  return id.slice(0, idx)
}

export function collectHospitalImagePublicIds(value: unknown): Set<string> {
  const ids = new Set<string>()
  walkForImagePublicIds(value, ids)
  return ids
}

function walkForImagePublicIds(value: unknown, out: Set<string>) {
  if (value === null || value === undefined) return
  if (typeof value === "string") return
  if (Array.isArray(value)) {
    for (const item of value) walkForImagePublicIds(item, out)
    return
  }
  if (typeof value !== "object") return
  const record = value as JsonRecord
  for (const [key, raw] of Object.entries(record)) {
    if (typeof raw === "string") {
      const lower = key.toLowerCase()
      if (lower.includes("publicid")) {
        const id = raw.trim()
        if (id.startsWith("hospitals/")) out.add(id)
      } else if (lower.includes("image") || lower.includes("logo")) {
        const fromUrl = extractMediaKeyFromUrl(raw, { prefix: "hospitals" })
        if (fromUrl) out.add(fromUrl)
      }
      continue
    }
    walkForImagePublicIds(raw, out)
  }
}

/** Section JSON keys on `Hospital` / `HospitalTranslation` — must match API routes. */
export const HOSPITAL_SECTION_KEYS = [
  "hero",
  "about",
  "gallery",
  "departments",
  "doctors",
  "accreditation",
  "technology",
  "visitProcess",
  "reviews",
  "location",
  "packages",
  "faq",
  "cta",
  "similar",
] as const

export type HospitalSectionKey = (typeof HOSPITAL_SECTION_KEYS)[number]

function asRecord(value: unknown): JsonRecord {
  if (value && typeof value === "object" && !Array.isArray(value)) return value as JsonRecord
  return {}
}

function str(value: unknown): string {
  return typeof value === "string" ? value : ""
}

function sanitizeHeroSection(raw: unknown): JsonRecord {
  const src = asRecord(raw)
  const virtualTourUrl = str(src.virtualTourUrl).trim()
  const galleryImages = Array.isArray(src.galleryImages)
    ? src.galleryImages
        .map((item) => {
          if (typeof item === "string") return { image: item.trim(), imagePublicId: "" }
          const r = asRecord(item)
          return {
            image: str(r.image).trim(),
            imagePublicId: str(r.imagePublicId).trim(),
          }
        })
        .filter((x) => x.image !== "")
    : []
  return { virtualTourUrl, heroStats: [], galleryImages }
}

function sanitizeAboutSection(raw: unknown): JsonRecord {
  const src = asRecord(raw)
  const aboutStats = Array.isArray(src.aboutStats)
    ? src.aboutStats.map((item) => {
        const r = asRecord(item)
        return {
          icon: str(r.icon),
          label: str(r.label),
          value: str(r.value),
          description: str(r.description),
        }
      })
    : []
  return {
    eyebrow: str(src.eyebrow),
    title: str(src.title),
    description: str(src.description),
    aboutStats,
  }
}

function sanitizeGallerySection(raw: unknown): JsonRecord {
  const src = asRecord(raw)
  const categories = Array.isArray(src.categories)
    ? src.categories.map((item) => ({ name: str(asRecord(item).name) }))
    : []
  const images = Array.isArray(src.images)
    ? src.images.map((item) => {
        const r = asRecord(item)
        return {
          title: str(r.title),
          image: str(r.image),
          category: str(r.category),
        }
      })
    : []
  const videos = Array.isArray(src.videos)
    ? src.videos.map((item) => {
        const r = asRecord(item)
        return {
          title: str(r.title),
          videoUrl: str(r.videoUrl),
          category: str(r.category),
        }
      })
    : []
  return {
    eyebrow: str(src.eyebrow),
    title: str(src.title),
    categories,
    images,
    videos,
  }
}

function sanitizeDepartmentsSection(raw: unknown): JsonRecord {
  const src = asRecord(raw)
  const departments = Array.isArray(src.departments)
    ? src.departments.map((item) => {
        const r = asRecord(item)
        return {
          icon: str(r.icon),
          title: str(r.title),
          description: str(r.description),
        }
      })
    : []
  return {
    eyebrow: str(src.eyebrow),
    title: str(src.title),
    subtitle: str(src.subtitle),
    departments,
  }
}

function sanitizeDoctorsSection(raw: unknown): JsonRecord {
  const src = asRecord(raw)
  const doctorIds = Array.isArray(src.doctorIds)
    ? src.doctorIds
        .filter((x): x is string => typeof x === "string" && x.trim() !== "")
        .map((id) => id.trim())
    : []
  return {
    eyebrow: str(src.eyebrow),
    title: str(src.title),
    primaryButtonText: str(src.primaryButtonText),
    primaryButtonLink: str(src.primaryButtonLink),
    doctorIds,
  }
}

function sanitizeAccreditationSection(raw: unknown): JsonRecord {
  const src = asRecord(raw)
  const accreditations = Array.isArray(src.accreditations)
    ? src.accreditations.map((item) => {
        const r = asRecord(item)
        return {
          name: str(r.name),
          date: str(r.date),
          description: str(r.description),
          logo: str(r.logo),
          certificateImage: str(r.certificateImage),
          issuer: str(r.issuer),
        }
      })
    : []
  return {
    eyebrow: str(src.eyebrow),
    title: str(src.title),
    subtitle: str(src.subtitle),
    accreditations,
  }
}

function sanitizeTechnologySection(raw: unknown): JsonRecord {
  const src = asRecord(raw)
  const technologies = Array.isArray(src.technologies)
    ? src.technologies.map((item) => {
        const r = asRecord(item)
        return {
          icon: str(r.icon),
          title: str(r.title),
          since: str(r.since),
          description: str(r.description),
        }
      })
    : []
  return {
    eyebrow: str(src.eyebrow),
    title: str(src.title),
    subtitle: str(src.subtitle),
    technologies,
  }
}

function sanitizeVisitProcessSection(raw: unknown): JsonRecord {
  const src = asRecord(raw)
  const steps = Array.isArray(src.steps)
    ? src.steps.map((item) => {
        const r = asRecord(item)
        return {
          icon: str(r.icon),
          title: str(r.title),
          description: str(r.description),
        }
      })
    : []
  return {
    eyebrow: str(src.eyebrow),
    title: str(src.title),
    subtitle: str(src.subtitle),
    steps,
  }
}

function sanitizeReviewsSection(raw: unknown): JsonRecord {
  const src = asRecord(raw)
  const reviews = Array.isArray(src.reviews)
    ? src.reviews.map((item) => {
        const r = asRecord(item)
        let rating: number | "" = ""
        if (typeof r.rating === "number" && Number.isFinite(r.rating)) rating = r.rating
        else if (r.rating === "") rating = ""
        return {
          rating,
          patientName: str(r.patientName),
          country: str(r.country),
          reviewText: str(r.reviewText),
          treatment: str(r.treatment),
          date: str(r.date),
          isFeatured: Boolean(r.isFeatured),
        }
      })
    : []
  return {
    eyebrow: str(src.eyebrow),
    title: str(src.title),
    reviews,
  }
}

function sanitizeLocationSection(raw: unknown): JsonRecord {
  const src = asRecord(raw)
  const contactInfo = Array.isArray(src.contactInfo)
    ? src.contactInfo.map((item) => {
        const r = asRecord(item)
        return { icon: str(r.icon), text: str(r.text) }
      })
    : []
  const extraCard = Array.isArray(src.extraCard)
    ? src.extraCard.map((item) => {
        const r = asRecord(item)
        return {
          icon: str(r.icon),
          label: str(r.label),
          value: str(r.value),
        }
      })
    : []
  return {
    eyebrow: str(src.eyebrow),
    title: str(src.title),
    googleMapsUrl: str(src.googleMapsUrl),
    contactInfoCardTitle: str(src.contactInfoCardTitle),
    contactInfo,
    contactButtonIcon: str(src.contactButtonIcon),
    contactButtonText: str(src.contactButtonText),
    contactButtonLink: str(src.contactButtonLink),
    extraCardTitle: str(src.extraCardTitle),
    extraCard,
  }
}

function sanitizePackagesSection(raw: unknown): JsonRecord {
  const src = asRecord(raw)
  return {
    eyebrow: str(src.eyebrow),
    title: str(src.title),
    subtitle: str(src.subtitle),
  }
}

function sanitizeFaqSection(raw: unknown): JsonRecord {
  const src = asRecord(raw)
  const faqs = Array.isArray(src.faqs)
    ? src.faqs.map((item) => {
        const r = asRecord(item)
        return { question: str(r.question), answer: str(r.answer) }
      })
    : []
  return {
    eyebrow: str(src.eyebrow),
    title: str(src.title),
    faqs,
  }
}

function sanitizeCtaSection(raw: unknown): JsonRecord {
  const src = asRecord(raw)
  const features = Array.isArray(src.features) ? src.features.map((x) => str(x)) : []
  const procedures = Array.isArray(src.procedures) ? src.procedures.map((x) => str(x)) : []
  return {
    eyebrow: str(src.eyebrow),
    title: str(src.title),
    subtitle: str(src.subtitle),
    features,
    buttonIcon: str(src.buttonIcon),
    buttonText: str(src.buttonText),
    buttonLink: str(src.buttonLink),
    formTitle: str(src.formTitle),
    fullNameLabel: str(src.fullNameLabel),
    phoneLabel: str(src.phoneLabel),
    emailLabel: str(src.emailLabel),
    procedureLabel: str(src.procedureLabel),
    procedures,
    messageLabel: str(src.messageLabel),
    formButtonIcon: str(src.formButtonIcon),
    formButtonText: str(src.formButtonText),
    formButtonLink: str(src.formButtonLink),
    endOfFormLabel: str(src.endOfFormLabel),
  }
}

function sanitizeSimilarSection(raw: unknown): JsonRecord {
  const src = asRecord(raw)
  return {
    eyebrow: str(src.eyebrow),
    title: str(src.title),
    primaryButtonText: str(src.primaryButtonText),
    primaryButtonLink: str(src.primaryButtonLink),
  }
}

function sanitizeHospitalSectionKey(key: HospitalSectionKey, raw: unknown): JsonRecord {
  switch (key) {
    case "hero":
      return sanitizeHeroSection(raw)
    case "about":
      return sanitizeAboutSection(raw)
    case "gallery":
      return sanitizeGallerySection(raw)
    case "departments":
      return sanitizeDepartmentsSection(raw)
    case "doctors":
      return sanitizeDoctorsSection(raw)
    case "accreditation":
      return sanitizeAccreditationSection(raw)
    case "technology":
      return sanitizeTechnologySection(raw)
    case "visitProcess":
      return sanitizeVisitProcessSection(raw)
    case "reviews":
      return sanitizeReviewsSection(raw)
    case "location":
      return sanitizeLocationSection(raw)
    case "packages":
      return sanitizePackagesSection(raw)
    case "faq":
      return sanitizeFaqSection(raw)
    case "cta":
      return sanitizeCtaSection(raw)
    case "similar":
      return sanitizeSimilarSection(raw)
    default:
      return {}
  }
}

/** Drops keys not produced by the dashboard hospital form so stale JSON is not persisted. */
export function sanitizePersistedHospitalSections(sections: Record<string, unknown>): Record<string, unknown> {
  const out: Record<string, unknown> = {}
  for (const key of HOSPITAL_SECTION_KEYS) {
    out[key] = sanitizeHospitalSectionKey(key, sections[key])
  }
  return out
}
