/**
 * Newsletter page data layer.
 *
 * Same pattern as homepage & contact: bundled defaults with
 * Strapi merge-over-defaults when enabled.
 */

import { fetchSingle, getMediaUrl } from "@/lib/strapi/client"
import { isStrapiEnabled } from "@/lib/strapi/config"
import { titleCase } from "@/lib/api/casing"
import { normalizeCmsLink } from "@/lib/api/links"
import type {
  NewsletterPageData,
  NewsletterPageItemData,
  NewsletterYearData,
  StrapiMedia,
} from "@/lib/strapi/types"

/* ------------------------------------------------------------------ */
/*  Bundled defaults                                                   */
/* ------------------------------------------------------------------ */

export const newsletterDefaults: NewsletterPageData = {
  hero: {
    heading: "MGM Group Newsletter",
    description:
      "Stay informed with the latest news, achievements, and updates from across our diverse business ventures.",
    mobileImage: "/assets/newsletter/hero-bg-mobile.png",
    desktopImage: "/assets/newsletter/Newsletter Banner.jpeg",
  },
  archive: {
    badge: "Newsletter Archive",
    badgeIcon: "",
    selectYearLabel: "Select Year:",
    watermarkText: "Our Newsletter",
    viewMoreLabel: "View more",
    years: [
      {
        year: "2026",
        items: [
          {
            month: "April 2026",
            title: "MGM Newsletter April 2026",
            pdfUrl: "/assets/newsletters/PDF/MGM Newsletter April 2026.pdf",
            thumbnail:
              "/assets/newsletters/thumbnails/MGM Newsletter April 2026.pdf.png",
          },
        ],
      },
      {
        year: "2025",
        items: [
          {
            month: "October 2025",
            title: "MGM Newsletter Oct 2025",
            pdfUrl: "/assets/newsletters/PDF/MGM Newsletter Oct 2025.pdf",
            thumbnail:
              "/assets/newsletters/thumbnails/MGM Newsletter Oct 2025.pdf.png",
          },
        ],
      },
      {
        year: "2024",
        items: [
          {
            month: "October 2024",
            title: "MGM Newsletter Oct 2024",
            pdfUrl: "/assets/newsletters/PDF/MGM Newsletter Oct 2024.pdf",
            thumbnail: "/assets/newsletters/thumbnails/MGM Newsletter Oct 2024.png",
          },
          {
            month: "April 2024",
            title: "MGM Newsletter Apr 2024",
            pdfUrl: "/assets/newsletters/PDF/MGM Newsletter Apr 2024.pdf",
            thumbnail:
              "/assets/newsletters/thumbnails/MGM Newsletter Apr 2024.pdf.png",
          },
        ],
      },
      {
        year: "2023",
        items: [
          {
            month: "April 2023",
            title: "MGM Newsletter Apr 2023",
            pdfUrl: "/assets/newsletters/PDF/MGM Newsletter Apr 2023.pdf",
            thumbnail:
              "/assets/newsletters/thumbnails/MGM Newsletter Apr 2023.pdf.png",
          },
        ],
      },
      {
        year: "2022",
        items: [
          {
            month: "October 2022",
            title: "MGM Newsletter Oct 2022",
            pdfUrl: "/assets/newsletters/PDF/MGM Newsletter Oct 2022.pdf",
            thumbnail:
              "/assets/newsletters/thumbnails/MGM Newsletter Oct 2022.pdf.png",
          },
        ],
      },
    ],
  },
  subscribe: {
    heading: "Subscribe to Our Newsletter",
    description:
      "Receive the latest updates delivered straight to your inbox every month.",
    emailPlaceholder: "Email ID ",
    ctaLabel: "Subscribe",
    ctaHref: "",
  },
}

/* ------------------------------------------------------------------ */
/*  Helpers                                                           */
/* ------------------------------------------------------------------ */

type AnyRec = Record<string, unknown>

/** Read a property from a Strapi entry, handling both v4 (attributes) and v5 (flat). */
function attr(entry: unknown): AnyRec {
  if (!entry || typeof entry !== "object") return {}
  const e = entry as AnyRec
  if (e.attributes && typeof e.attributes === "object") {
    return e.attributes as AnyRec
  }
  return e
}

function str(val: unknown, fallback = ""): string {
  if (typeof val === "string") return val.trim() !== "" ? val : fallback
  if (typeof val === "number") return String(val)
  return fallback
}

function media(val: unknown): string {
  return getMediaUrl(val as StrapiMedia | null | undefined)
}

function asArr(v: unknown): AnyRec[] {
  return Array.isArray(v) ? (v as AnyRec[]) : []
}

function normalizeKey(value: string): string {
  return value.trim().toLowerCase().replace(/\s+/g, " ")
}

function findFallbackItem(
  fallbackYears: NewsletterYearData[],
  year: string,
  month: string,
  title: string,
): NewsletterPageItemData | undefined {
  const fallbackYear = fallbackYears.find((group) => group.year === year)
  if (!fallbackYear) return undefined

  const monthKey = normalizeKey(month)
  const titleKey = normalizeKey(title)

  return fallbackYear.items.find((item) => {
    return normalizeKey(item.month) === monthKey || normalizeKey(item.title) === titleKey
  })
}

/* ------------------------------------------------------------------ */
/*  Public API                                                        */
/* ------------------------------------------------------------------ */

export async function getNewsletterData(): Promise<NewsletterPageData> {
  const d = newsletterDefaults

  if (!isStrapiEnabled) return d

  const entry = await fetchSingle<AnyRec>("newsletter-page")

  if (!entry) return d

  const hero = attr(entry.hero)
  const archive = attr(entry.archive)
  const subscribe = attr(entry.subscribe)
  const yearRows = asArr(archive.years)

  const mappedYears = yearRows.map((row) => {
    const group = attr(row)
    const year = str(group.year)
    return {
      year,
      items: asArr(group.items).map((row) => {
        const item = attr(row)
        const month = str(item.month)
        const title = str(item.title)
        const fallback = findFallbackItem(d.archive.years, year, month, title)

        return {
          month: str(item.month, fallback?.month || ""),
          title: str(item.title, fallback?.title || ""),
          pdfUrl: media(item.pdfFile) || fallback?.pdfUrl || "",
          thumbnail: media(item.thumbnail_1x1) || fallback?.thumbnail || "",
        }
      }).filter((item) => item.thumbnail),
    }
  })
  const seenYears = new Set(mappedYears.map((y) => y.year))
  const mergedYears = [
    ...mappedYears,
    ...d.archive.years.filter((dy) => !seenYears.has(dy.year)),
  ].sort((a, b) => {
    const an = parseInt(a.year, 10)
    const bn = parseInt(b.year, 10)
    if (!Number.isNaN(an) && !Number.isNaN(bn)) return bn - an
    return b.year.localeCompare(a.year)
  })

  return {
    hero: {
      heading: str(hero.heading, d.hero.heading),
      description: str(hero.description, d.hero.description),
      mobileImage: media(hero.mobileImage_4x3) || d.hero.mobileImage,
      desktopImage: media(hero.desktopImage_5x2) || d.hero.desktopImage,
    },
    archive: {
      badge: str(archive.badge, d.archive.badge),
      badgeIcon: d.archive.badgeIcon,
      selectYearLabel: str(archive.selectYearLabel, d.archive.selectYearLabel),
      watermarkText: titleCase(str(archive.watermarkText, d.archive.watermarkText)),
      viewMoreLabel: str(archive.viewMoreLabel, d.archive.viewMoreLabel),
      years: mergedYears,
    },
    subscribe: {
      heading: str(subscribe.heading, d.subscribe.heading),
      description: str(subscribe.description, d.subscribe.description),
      emailPlaceholder: str(subscribe.emailPlaceholder, d.subscribe.emailPlaceholder),
      ctaLabel: str(subscribe.ctaButtonText, d.subscribe.ctaLabel),
      ctaHref: normalizeCmsLink(subscribe.ctaButtonLink, d.subscribe.ctaHref),
    },
  }
}
