'use client'; import { ArrowDownRight, ArrowUpRight } from 'lucide-react'; import Link from 'next/link'; import { t } from '@/i18n'; import { cn } from '@/lib/cn'; import { fixed, formatValue } from '@/lib/format'; import { routes } from '@/lib/site'; import type { FormatSpec } from '@/lib/types'; import type { ExtremeFacet } from '@/lib/types-analytics'; import { SourceLine } from '@/components/charts/source-line'; function changeText(row: ExtremeFacet['rows'][number], metric: ExtremeFacet['metric'], spec: FormatSpec): string { if (metric === 'pct' && row.delta_pct != null) return `${row.delta_pct >= 0 ? '+' : '−'}${fixed(Math.abs(row.delta_pct), 1)} %`; if (row.delta == null) return t('common.na'); const sign = row.delta >= 0 ? '+' : '−'; if (metric === 'points') return `${sign}${fixed(Math.abs(row.delta), spec.precision ?? 1)} pts`; return `${sign}${formatValue(Math.abs(row.delta), spec)}`; } /** One extremes facet: title, direction, rows start → end with the change bar. Neutral colours (increase/decrease). */ export function ExtremeFacetBlock({ facet }: { facet: ExtremeFacet }) { const ind = facet.indicator; const spec: FormatSpec = { format: ind.format, unit: ind.unit, unit_short: ind.unit_short, precision: ind.precision, frequency: 'A', name: ind.short_name ?? ind.name, higher_is_better: ind.higher_is_better }; const up = facet.direction === 'up'; const Icon = up ? ArrowUpRight : ArrowDownRight; const mags = facet.rows.map((r) => Math.abs((facet.metric === 'pct' ? r.delta_pct : r.delta) ?? 0)); const max = Math.max(1e-9, ...mags); const y0 = facet.rows[0]?.year_start; const y1 = facet.rows[0]?.year_end; const payload = { indicator: { slug: ind.slug, name: ind.name ?? ind.slug, format: ind.format, unit: ind.unit, unit_short: ind.unit_short, precision: ind.precision, frequency: 'A' as const, higher_is_better: ind.higher_is_better }, value: null, country: null, downloadHref: routes.indicatorDownload(ind.slug) }; return (

{facet.title}

{up ? t('extremes.direction.up') : t('extremes.direction.down')} · {ind.name} {y0 && y1 ? ( · {y0}–{y1} · {t('extremes.n', { n: facet.n })} ) : null}

{t('extremes.openRanking')} → {t('extremes.explore')} →
    {facet.rows.map((r, i) => { const mag = Math.abs((facet.metric === 'pct' ? r.delta_pct : r.delta) ?? 0); const pct = (mag / max) * 100; return (
  1. {i + 1} {r.country.flag} {r.country.name}
    {changeText(r, facet.metric, spec)} {r.formatted_start ?? formatValue(r.value_start, spec)} → {t('extremes.to')} {r.formatted_end ?? formatValue(r.value_end, spec)} {r.year_start && r.year_end && (r.year_start !== y0 || r.year_end !== y1) ? ` (${r.year_start}–${r.year_end})` : ''}
  2. ); })}
); }