import { commitImage } from "@/lib/media-manager/commit"
import { MEDIA_FILE_BASE } from "@/lib/media-manager/file-names"
import { revokeStagedImage } from "@/lib/media-manager/stage"
import type { StagedImage } from "@/lib/media-manager/types"
import type { Language } from "@/components/dashboard/shared/LanguageTabs"
import type { HospitalAccreditationData } from "@/components/dashboard/hospitals/HospitalAccreditationSection"
import type { HospitalGalleryData } from "@/components/dashboard/hospitals/HospitalGallerySection"
import type { HospitalHeroData } from "@/components/dashboard/hospitals/HospitalHeroSection"
import type { HospitalBasicInfoStoredFields } from "@/components/dashboard/hospitals/HospitalBasicInfo"

export type HospitalPendingLocaleKey = `${Language}:${number}`

export function hospitalPendingKey(locale: Language, index: number): HospitalPendingLocaleKey {
  return `${locale}:${index}`
}

export function parseHospitalPendingKey(key: string): { locale: Language; index: number } | null {
  const colon = key.indexOf(":")
  if (colon <= 0) return null
  const locale = key.slice(0, colon) as Language
  if (locale !== "en" && locale !== "ar" && locale !== "tr") return null
  const index = Number(key.slice(colon + 1))
  if (!Number.isInteger(index) || index < 0) return null
  return { locale, index }
}

export interface HospitalPendingImages {
  mainPhoto: StagedImage | null
  heroGallery: Map<HospitalPendingLocaleKey, StagedImage>
  galleryImages: Map<HospitalPendingLocaleKey, StagedImage>
  accreditationLogo: Map<HospitalPendingLocaleKey, StagedImage>
  accreditationCertificate: Map<HospitalPendingLocaleKey, StagedImage>
}

export function createEmptyHospitalPendingImages(): HospitalPendingImages {
  return {
    mainPhoto: null,
    heroGallery: new Map(),
    galleryImages: new Map(),
    accreditationLogo: new Map(),
    accreditationCertificate: new Map(),
  }
}

export function hospitalPendingHasAny(pending: HospitalPendingImages): boolean {
  return (
    !!pending.mainPhoto ||
    pending.heroGallery.size > 0 ||
    pending.galleryImages.size > 0 ||
    pending.accreditationLogo.size > 0 ||
    pending.accreditationCertificate.size > 0
  )
}

export interface HospitalLocaleImageSlice {
  hero: HospitalHeroData
  gallery: HospitalGalleryData
  accreditation: HospitalAccreditationData
}

export interface HospitalFormImageSlice {
  basicInfo: HospitalBasicInfoStoredFields
  translations: Record<Language, HospitalLocaleImageSlice>
}

export interface CommitPendingHospitalImagesOptions {
  hospitalSlug: string
  hospitalId?: string
  pending: HospitalPendingImages
}

/** Upload all pending hospital images, merge URLs into form slice, clear pending. */
export async function commitPendingHospitalImages(
  slice: HospitalFormImageSlice,
  options: CommitPendingHospitalImagesOptions
): Promise<HospitalFormImageSlice> {
  const hospitalSlug = options.hospitalSlug.trim()
  if (!hospitalSlug) {
    throw new Error("Hospital slug is required before saving images.")
  }

  let basicInfo = { ...slice.basicInfo }
  const translations = {
    en: {
      hero: { ...slice.translations.en.hero, galleryImages: [...slice.translations.en.hero.galleryImages] },
      gallery: {
        ...slice.translations.en.gallery,
        images: slice.translations.en.gallery.images.map((item) => ({ ...item })),
      },
      accreditation: {
        ...slice.translations.en.accreditation,
        accreditations: slice.translations.en.accreditation.accreditations.map((item) => ({ ...item })),
      },
    },
    ar: {
      hero: { ...slice.translations.ar.hero, galleryImages: [...slice.translations.ar.hero.galleryImages] },
      gallery: {
        ...slice.translations.ar.gallery,
        images: slice.translations.ar.gallery.images.map((item) => ({ ...item })),
      },
      accreditation: {
        ...slice.translations.ar.accreditation,
        accreditations: slice.translations.ar.accreditation.accreditations.map((item) => ({ ...item })),
      },
    },
    tr: {
      hero: { ...slice.translations.tr.hero, galleryImages: [...slice.translations.tr.hero.galleryImages] },
      gallery: {
        ...slice.translations.tr.gallery,
        images: slice.translations.tr.gallery.images.map((item) => ({ ...item })),
      },
      accreditation: {
        ...slice.translations.tr.accreditation,
        accreditations: slice.translations.tr.accreditation.accreditations.map((item) => ({ ...item })),
      },
    },
  }

  if (options.pending.mainPhoto) {
    const committed = await commitImage({
      entity: "hospital",
      staged: options.pending.mainPhoto,
      hospitalSlug,
      section: "main-photo",
      fileBaseName: MEDIA_FILE_BASE.mainPhoto,
      hospitalId: options.hospitalId,
    })
    revokeStagedImage(options.pending.mainPhoto)
    basicInfo = {
      ...basicInfo,
      image: committed.url,
      imagePublicId: committed.publicId,
    }
    options.pending.mainPhoto = null
  }

  async function commitLocaleMap(
    map: Map<HospitalPendingLocaleKey, StagedImage>,
    section: "gallery" | "certificates",
    fileBaseName: string,
    apply: (locale: Language, index: number, url: string, publicId: string) => void
  ) {
    const keys = [...map.keys()].sort()
    for (const key of keys) {
      const staged = map.get(key)
      if (!staged) continue
      const parsed = parseHospitalPendingKey(key)
      if (!parsed) continue
      const committed = await commitImage({
        entity: "hospital",
        staged,
        hospitalSlug,
        section,
        fileBaseName,
        fileIndex: parsed.index,
        hospitalId: options.hospitalId,
      })
      revokeStagedImage(staged)
      map.delete(key)
      apply(parsed.locale, parsed.index, committed.url, committed.publicId)
    }
  }

  await commitLocaleMap(
    options.pending.heroGallery,
    "gallery",
    MEDIA_FILE_BASE.heroGallery,
    (locale, index, url, publicId) => {
    const items = translations[locale].hero.galleryImages
    if (items[index]) {
      items[index] = { ...items[index], image: url, imagePublicId: publicId }
    }
  })

  await commitLocaleMap(options.pending.galleryImages, "gallery", MEDIA_FILE_BASE.gallery, (locale, index, url) => {
    const items = translations[locale].gallery.images
    if (items[index]) {
      items[index] = { ...items[index], image: url }
    }
  })

  await commitLocaleMap(
    options.pending.accreditationLogo,
    "certificates",
    MEDIA_FILE_BASE.accreditationLogo,
    (locale, index, url) => {
    const items = translations[locale].accreditation.accreditations
    if (items[index]) {
      items[index] = { ...items[index], logo: url }
    }
  })

  await commitLocaleMap(
    options.pending.accreditationCertificate,
    "certificates",
    MEDIA_FILE_BASE.accreditationCertificate,
    (locale, index, url) => {
      const items = translations[locale].accreditation.accreditations
      if (items[index]) {
        items[index] = { ...items[index], certificateImage: url }
      }
    }
  )

  return { basicInfo, translations }
}

export function clearHospitalPendingImages(pending: HospitalPendingImages) {
  if (pending.mainPhoto) revokeStagedImage(pending.mainPhoto)
  pending.mainPhoto = null
  for (const map of [
    pending.heroGallery,
    pending.galleryImages,
    pending.accreditationLogo,
    pending.accreditationCertificate,
  ]) {
    for (const staged of map.values()) {
      revokeStagedImage(staged)
    }
    map.clear()
  }
}
