import type { Metadata } from 'next'
import { CourseCard } from '@/components/Cards'
import { Catalog, type CatalogItem } from '@/components/Catalog'
import { Shell } from '@/components/Shell'
import { publicConfig } from '@/lib/config'
import { pageMeta } from '@/lib/meta'
import { type Locale, categoryOf, loadPage, loadSite, price } from '@/lib/site'

type Props = {
  params: Promise<{ locale: Locale }>
  searchParams: Promise<{ category?: string }>
}

export async function generateMetadata({ params }: Props): Promise<Metadata> {
  const { locale } = await params
  const c = await loadPage('catalogue', locale)
  return pageMeta(locale, '/courses', c.seo?.title, c.seo?.description)
}

/**
 * Every course, with the filters over them.
 *
 * The cards are rendered here, on the server, and handed to `Catalog` as children; it only decides
 * which of them to show. So the whole catalogue is in the HTML — a crawler indexes every course, and
 * a visitor whose JavaScript has not arrived still sees them all — and filtering costs no request.
 */
export default async function Courses({ params, searchParams }: Props) {
  const { locale } = await params
  const { category } = await searchParams
  const [{ settings: s, courses, categories }, cat] = await Promise.all([
    loadSite(locale),
    loadPage('catalogue', locale),
  ])
  const cfg = publicConfig()
  const f = cat.filters

  // The level is a phrase the platform stores per language, not a fixed list, so the options are the
  // phrases actually in use. A level added on the platform appears here with nothing changed.
  const levels = [...new Set(courses.map((c) => (c.level || '').trim()).filter(Boolean))]

  const items: CatalogItem[] = courses.map((c) => {
    const k = categoryOf(c, categories)
    return {
      slug: c.slug,
      // Searching matches what the visitor can see on the card plus the category it sits under.
      haystack: [c.title, c.titleShort, c.tagline, c.level, k?.name].filter(Boolean).join(' ').toLowerCase(),
      categorySlug: k?.slug ?? null,
      level: (c.level || '').trim(),
      status: (c.status || 'soon') as CatalogItem['status'],
      // What it costs TODAY, offer included, so «lowest price» orders by what is actually paid.
      price: c.price?.amount === null || c.price?.amount === undefined ? null : Number(price(c, s).now.replace(/[^\d.]/g, '')) || null,
    }
  })

  return (
    <Shell locale={locale} path="/courses" settings={s} courses={courses} config={cfg}>
      <div className="container pagehead">
        <h1>{cat.h1}</h1>
        <p>{cat.lead}</p>
      </div>
      <section className="container">
        <Catalog
          items={items}
          categories={categories.map((k) => ({ slug: k.slug, name: k.name }))}
          levels={levels}
          forms={cat.count || {}}
          locale={locale}
          pageSize={cfg.pageSize}
          initialCategory={category ?? null}
          labels={{
            search: f?.search || '',
            category: f?.category || '',
            level: f?.level || '',
            status: f?.status || '',
            all: f?.all || '',
            allLevels: f?.allLevels || '',
            available: s.status?.live || '',
            partial: s.status?.partial || '',
            coming: s.status?.soon || '',
            results: f?.results || '',
            sort: f?.sort || '',
            sortDefault: f?.sortDefault || '',
            sortPrice: f?.sortPrice || '',
            empty: f?.empty || '',
            page: f?.page || '',
          }}
        >
          {courses.map((c) => (
            <CourseCard key={c.id} course={c} settings={s} locale={locale}
                        category={categoryOf(c, categories)} priceWasLabel={cat.labels?.priceWas} />
          ))}
        </Catalog>
      </section>
    </Shell>
  )
}
