import type { Catalogue, Course, Setting } from '@/payload-types'
import { type Locale, localHref, media, price } from '@/lib/site'

const TONE: Record<string, string> = {
  'royal-700': 'var(--tk-royal-700)',
  'royal-800': 'var(--tk-royal-800)',
  'azure-700': 'var(--tk-azure-700)',
  'navy-900': 'var(--tk-navy-900)',
  'navy-700': 'var(--tk-navy-700)',
}

export function StatusBadge({ course, settings }: { course: Course; settings: Setting }) {
  // the platform always sends a status; a CMS row made only for a picture may not have one
  const status = course.status || 'soon'
  const cls = { live: 'badge--live', partial: 'badge--soon', soon: 'badge--plain' }[status]
  const icon = { live: '●', partial: '◐', soon: '○' }[status]
  return (
    <span className={`badge ${cls}`}>
      <span aria-hidden="true">{icon}</span>
      {settings.status?.[status]}
    </span>
  )
}

export function CourseCard({
  course: c,
  locale,
  settings,
  level = 3,
}: {
  course: Course
  locale: Locale
  settings: Setting
  level?: 2 | 3
}) {
  const url = localHref(locale, `/courses/${c.slug}`)
  // A course that is still being prepared used to show the brand mark instead of its picture. That made
  // sense when «coming soon» was one card among five; with courses arriving across subjects and stages it
  // turns the catalogue into a wall of identical logos. The badge already says it is coming — the picture
  // can say what it is about. Falling back to the picture set on the platform when the CMS has no poster.
  const poster = media(c.poster)
  const thumb = poster?.sizes?.card?.url || poster?.url || (c as { image?: string | null }).image || null
  const facts = (c.facts || []).slice(0, 2).map((f) => f.text).join(' · ')
  const H = `h${level}` as 'h2' | 'h3'
  const money = price(c, settings)
  return (
    <article className="card course-card">
      {thumb ? (
        <div className="thumb thumb--photo">
          <img src={thumb} alt="" width={640} height={360} loading="lazy" />
        </div>
      ) : (
        <div className="thumb" style={{ background: TONE[c.tone || 'royal-700'] }}>
          <img src="/brand/thinkera-mark-white.svg" alt="" width={120} height={120} />
        </div>
      )}
      <StatusBadge course={c} settings={settings} />
      <H className="ccard-title">
        <a href={url}>{c.title}</a>
      </H>
      <p className="muted">{c.tagline}</p>
      <p className="meta">{facts}</p>
      <div className="spacer" />
      <div className="foot">
        <span className="price">
          {money.now}
          {money.was ? <s className="price-was">{money.was}</s> : null}
        </span>
        <a className="btn btn--secondary" href={url}>
          {c.status !== 'soon' ? settings.cta?.primary : settings.cta?.notify}
        </a>
      </div>
    </article>
  )
}

type Labels = NonNullable<Catalogue['labels']>
type Unit = NonNullable<Course['units']>[number]

/** Which word stands for the lessons that are the course itself, rather than the ones added above it. */
function coreWord(labels: Labels, track?: string): string {
  return track === 'pro' ? labels.fromCore || labels.fromBook || '' : labels.fromBook || ''
}

function UnitCount({ u, labels, track }: { u: Unit; labels: Labels; track?: string }) {
  if (u.kind === 'labs')
    return (
      <>
        <span className="num">{u.lessons}</span> {labels.labsWord}
      </>
    )
  if (u.kind === 'projects')
    return (
      <>
        <span className="num">{u.lessons}</span> {labels.projectsWord}
      </>
    )
  if (u.book !== null && u.book !== undefined)
    return (
      <>
        <span className="num">{u.book}</span> {coreWord(labels, track)} + <span className="num">{u.lessons - u.book}</span> {labels.added}
      </>
    )
  return (
    <>
      <span className="num">{u.lessons}</span> {labels.lessonsWord}
    </>
  )
}

export function UnitList({ course, labels }: { course: Course; labels: Labels }) {
  // the track comes from the platform feed and rides on the course; a course the CMS alone knows has none
  const track = (course as Course & { track?: string }).track
  return (
    <ol className="unit-list">
      {(course.units || []).map((u) => {
        const added = u.source === 'added'
        return (
          <li key={u.id || u.n} className={added ? 'is-added' : ''}>
            <span className="n">{u.n}</span>
            <span className="name">
              {u.name}
              {added ? <span className="unit-flag">{labels.addedUnit}</span> : null}
            </span>
            <span className="c">
              <UnitCount u={u} labels={labels} track={track} />
            </span>
          </li>
        )
      })}
    </ol>
  )
}
