/**
 * StatCards — trois cartes synthétiques affichées sur le Dashboard.
 *
 *  - Simulations restantes (barre de progression pour Free, "Illimitées" ailleurs)
 *  - NCLC estimé (dernière simulation)
 *  - Dernier score (+ delta vs précédent)
 *
 * Règle H : aucune logique métier de gating ici — le parent décide du rendu
 *           global via hasAccess. Ce composant ne fait que formater les
 *           valeurs déjà fournies.
 * Règle L : tokens du design system exclusivement.
 */

import { Card } from '@/shared/ui/Card'
import { formatRelativeDate } from '@/shared/lib/date'
import { isEcrit } from '@/entities/production/lib'
import type { SimulationListItem } from '@/entities/production/types'
import type { Plan } from '@/entities/user/lib'

interface StatCardsProps {
  plan: Plan
  simulationsUsed: number
  /** null = illimité (Standard/Premium), number = reste (Free). */
  simulationsRemaining: number | null
  /** Liste des dernières simulations (index 0 = la plus récente). */
  recentSimulations: readonly SimulationListItem[]
}

function formatNclc(n: number): string {
  return n.toLocaleString('fr-FR', { maximumFractionDigits: 1 })
}

function formatScore(value: number): string {
  return value.toLocaleString('fr-FR', { maximumFractionDigits: 1 })
}

function StatShell({ label, children }: { label: string; children: React.ReactNode }) {
  return (
    <Card variant="default" className="p-4">
      <p className="text-[11px] font-semibold uppercase tracking-wider text-ink-tertiary">
        {label}
      </p>
      <div className="mt-2 space-y-2">{children}</div>
    </Card>
  )
}

function SimulationsRestantesCard({
  plan,
  simulationsUsed,
  simulationsRemaining,
}: {
  plan: Plan
  simulationsUsed: number
  simulationsRemaining: number | null
}) {
  if (simulationsRemaining === null) {
    return (
      <StatShell label="Simulations">
        <p className="text-2xl font-extrabold tabular-nums text-ink-primary">Illimitées</p>
        <p className="text-xs text-ink-secondary">
          {simulationsUsed} effectuée{simulationsUsed > 1 ? 's' : ''}
        </p>
      </StatShell>
    )
  }

  const total = simulationsUsed + simulationsRemaining
  const pct = total > 0 ? (simulationsUsed / total) * 100 : 0

  return (
    <StatShell label="Simulations restantes">
      <p className="tabular-nums text-ink-primary">
        <span className="text-2xl font-extrabold">{simulationsRemaining}</span>
        <span className="text-lg font-medium text-ink-secondary">/{total}</span>
      </p>
      <div
        className="h-1.5 overflow-hidden rounded-full bg-surface-hover"
        role="progressbar"
        aria-valuemin={0}
        aria-valuemax={total}
        aria-valuenow={simulationsUsed}
        aria-label="Simulations utilisées"
      >
        <div
          className="h-full bg-brand transition-[width] duration-500"
          style={{ width: `${pct}%` }}
        />
      </div>
      {plan === 'free' && (
        <p className="text-xs text-ink-tertiary">Renouvellement offert à l'upgrade</p>
      )}
    </StatShell>
  )
}

function NclcCard({ lastSim }: { lastSim: SimulationListItem | null }) {
  if (!lastSim || lastSim.nclc === null) {
    return (
      <StatShell label="NCLC estimé">
        <p className="text-2xl font-extrabold tabular-nums text-ink-primary">—</p>
        <p className="text-xs text-ink-tertiary">
          Démarrez une simulation pour estimer votre niveau.
        </p>
      </StatShell>
    )
  }

  const nclc = lastSim.nclc
  const inTarget = nclc >= 7

  return (
    <StatShell label="NCLC estimé">
      <p className="text-2xl font-extrabold tabular-nums text-ink-primary">{formatNclc(nclc)}</p>
      <span className="inline-flex items-center rounded-full bg-brand-soft px-2.5 py-0.5 text-[11px] font-semibold text-brand-text">
        {inTarget ? 'Dans la cible CLB 7+' : 'Visez la cible CLB 7+'}
      </span>
    </StatShell>
  )
}

function DernierScoreCard({
  recentSimulations,
}: {
  recentSimulations: readonly SimulationListItem[]
}) {
  const lastWithScore = recentSimulations.find((s) => s.score !== null) ?? null
  if (!lastWithScore || lastWithScore.score === null) {
    return (
      <StatShell label="Dernier score">
        <p className="text-2xl font-extrabold tabular-nums text-ink-primary">—</p>
        <p className="text-xs text-ink-tertiary">Aucun score enregistré.</p>
      </StatShell>
    )
  }

  // Précédente simulation avec score, pour calculer le delta.
  const previous =
    recentSimulations.filter((s) => s.id !== lastWithScore.id && s.score !== null).at(0) ?? null
  const delta = previous && previous.score !== null ? lastWithScore.score - previous.score : null

  const type = isEcrit(lastWithScore.tache) ? 'Écrit' : 'Oral'
  const relative = formatRelativeDate(lastWithScore.created_at)

  return (
    <StatShell label="Dernier score">
      <p className="tabular-nums text-ink-primary">
        <span className="text-2xl font-extrabold">{formatScore(lastWithScore.score)}</span>
        <span className="text-lg font-medium text-ink-secondary">/20</span>
      </p>
      <div className="flex flex-wrap items-center gap-x-2 gap-y-1 text-xs text-ink-secondary">
        <span>{type}</span>
        <span aria-hidden="true" className="text-ink-tertiary">
          ·
        </span>
        <span>{relative}</span>
        {delta !== null && delta !== 0 && (
          <span className={delta > 0 ? 'font-semibold text-success' : 'font-semibold text-warning'}>
            {delta > 0 ? '+' : ''}
            {formatScore(delta)} vs précédent
          </span>
        )}
      </div>
    </StatShell>
  )
}

export function StatCards({
  plan,
  simulationsUsed,
  simulationsRemaining,
  recentSimulations,
}: StatCardsProps) {
  const lastSim = recentSimulations.at(0) ?? null

  return (
    <section
      aria-label="Indicateurs de préparation"
      className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3"
    >
      <SimulationsRestantesCard
        plan={plan}
        simulationsUsed={simulationsUsed}
        simulationsRemaining={simulationsRemaining}
      />
      <NclcCard lastSim={lastSim} />
      <DernierScoreCard recentSimulations={recentSimulations} />
    </section>
  )
}
