import type { Course } from '@/payload-types'

/**
 * The course catalogue, read from the learning platform.
 *
 * The platform owns it: which courses exist, their names, what they cover, what they cost and where they
 * stand are set on each course there, and this site prints them. The CMS keeps only what is about how the
 * site shows a course — its picture, the card colour, the free-lesson videos on its page — and it stands in
 * for the platform when the platform cannot be reached, so a page never goes blank for want of it.
 */

type Lang = { title: string; titleShort: string; tagline: string; audience: string; level: string; instruction: string;
  facts: string[]; includes: string[]; outcomes: string[]; availability: string; priceNote: string;
  units: { n: number; name: string; kind: 'lessons' | 'labs' | 'projects'; source: 'book' | 'added';
    lessons: number; book: number | null }[] }

export type FeedCourse = {
  id: number
  slug: string
  status: 'live' | 'partial' | 'soon'
  visible: boolean
  category: number
  enrolUrl: string
  price: { cost: number; offer: number | null; offerEnds: string | null; currency: string } | null
  ar: Lang
  en: Lang
}

export type FeedCategory = { id: number; slug: string; name: { ar: string; en: string }; order: number }

export type Feed = { generated: number; categories: FeedCategory[]; courses: FeedCourse[] }

/** Where to ask. PLATFORM_INTERNAL_URL is for a server that reaches the platform on a shorter path. */
function base(): string {
  return (process.env.PLATFORM_INTERNAL_URL || process.env.PLATFORM_URL || '').trim().replace(/\/+$/, '')
}

/**
 * The catalogue, or null when there is no platform to ask or it did not answer in time.
 * Next keeps the answer for five minutes, so a page is not a round trip to the platform.
 */
export async function catalogueFeed(): Promise<Feed | null> {
  const root = base()
  if (!root) return null
  try {
    const res = await fetch(`${root}/local/thinkera/feed.php`, {
      next: { revalidate: 300, tags: ['catalogue'] },
      signal: AbortSignal.timeout(4000),
    })
    if (!res.ok) return null
    const feed = (await res.json()) as Feed
    return feed && Array.isArray(feed.courses) ? feed : null
  } catch {
    return null
  }
}

/** A list of lines as the CMS shapes a list, so every page that already prints one keeps working. */
const rows = (slug: string, key: string, items: string[]) =>
  items.map((text, i) => ({ id: `${slug}-${key}-${i}`, text }))

/**
 * One platform course as the site's Course, in one language, wearing the CMS row of the same slug for the
 * things only the site decides. A course the CMS has never heard of still gets a page: it simply shows no
 * picture and the default card colour until someone gives it one.
 */
export function fromFeed(fc: FeedCourse, order: number, locale: 'ar' | 'en', cms?: Course): Course & { categoryId: number } {
  const t = fc[locale]
  const fallback = locale === 'en' ? fc.ar : null        // an English field left empty borrows the Arabic one
  const pick = (k: keyof Lang) => (t[k] as string) || (fallback ? (fallback[k] as string) : '')
  return {
    ...(cms || ({} as Course)),
    id: cms?.id ?? (`p${fc.id}` as unknown as number),
    slug: fc.slug,
    status: fc.status,
    order,
    title: pick('title'),
    titleShort: t.titleShort || null,
    tagline: pick('tagline'),
    audience: pick('audience'),
    level: pick('level'),
    instruction: pick('instruction'),
    availability: pick('availability'),
    facts: rows(fc.slug, 'f', t.facts.length ? t.facts : fallback?.facts || []),
    includes: rows(fc.slug, 'i', t.includes.length ? t.includes : fallback?.includes || []),
    outcomes: rows(fc.slug, 'o', t.outcomes.length ? t.outcomes : fallback?.outcomes || []),
    units: t.units.map((u, i) => ({ id: `${fc.slug}-u-${i}`, ...u })),
    price: {
      amount: fc.price ? fc.price.cost : null,
      offer: fc.price?.offer ?? null,
      // a plain «2026-10-15» from the platform, read as that day wherever this runs
      offerEnds: fc.price?.offerEnds ? `${fc.price.offerEnds}T00:00:00.000Z` : null,
      note: pick('priceNote') || null,
    },
    platformUrl: fc.enrolUrl,
    tone: cms?.tone || 'royal-700',
    categoryId: fc.category,
  } as Course & { categoryId: number }
}
