'use client'; import { ArrowRight, ChevronDown, ChevronUp, GripVertical, Plus, X } from 'lucide-react'; import Link from 'next/link'; import { useRouter } from 'next/navigation'; import { useCallback, useMemo, useState } from 'react'; import { t } from '@/i18n'; import { cn } from '@/lib/cn'; import { COMPARE_GROUP_PRESETS } from '@/lib/compare-presets'; import { MAX_COMPARE_COUNTRIES, MIN_COMPARE_COUNTRIES } from '@/lib/compare-state'; import { routes } from '@/lib/site'; import type { CountryLite } from '@/lib/types-compare'; import { seriesVar } from '@/components/charts/palette'; import { COMPARE_PRESETS } from '@/components/home/compare-teaser'; import { CountryPickerSheet, CountryTypeahead } from './country-picker'; /** * /compare landing: typeahead + ordered chips (drag on desktop, up/down buttons everywhere), presets * (G7, Nordics, BRICS, USMCA…, "Canada vs peers" from /similar) and the Compare button → /compare/a/b/c. * On phones the chip row is sticky under the header and the picker opens as a bottom sheet. */ export function CompareBuilder({ countries, peers, initial = [] }: { countries: CountryLite[]; peers: CountryLite[]; initial?: string[] }) { const router = useRouter(); const bySlug = useMemo(() => new Map(countries.map((c) => [c.slug, c])), [countries]); const [selected, setSelected] = useState(() => initial.filter((s) => bySlug.has(s)).slice(0, MAX_COMPARE_COUNTRIES)); const [sheet, setSheet] = useState(false); const [dragFrom, setDragFrom] = useState(null); const exclude = useMemo(() => new Set(selected), [selected]); const chosen = selected.map((s) => bySlug.get(s)!).filter(Boolean); const canGo = selected.length >= MIN_COMPARE_COUNTRIES; const full = selected.length >= MAX_COMPARE_COUNTRIES; const add = useCallback((c: CountryLite) => setSelected((s) => (s.includes(c.slug) || s.length >= MAX_COMPARE_COUNTRIES ? s : [...s, c.slug])), []); const remove = (slug: string) => setSelected((s) => s.filter((x) => x !== slug)); const move = (from: number, to: number) => setSelected((s) => { if (to < 0 || to >= s.length || from === to) return s; const next = [...s]; const [item] = next.splice(from, 1); next.splice(to, 0, item!); return next; }); const go = () => { if (canGo) router.push(routes.compare(...selected)); }; const peerPreset = peers.length >= 2 ? ['canada', ...peers.filter((p) => p.slug !== 'canada').slice(0, 5).map((p) => p.slug)] : null; return (
{/* Selected chips — sticky on phones */}
    {chosen.map((c, i) => (
  • {c.flag} {c.name}
  • ))}
{/* Ordered list with reorder controls */}
{t('compare.builder.selected')} · {selected.length}/{MAX_COMPARE_COUNTRIES}
{chosen.length === 0 ? (

{t('compare.builder.empty')}

) : (
    {chosen.map((c, i) => (
  1. setDragFrom(i)} onDragOver={(e) => e.preventDefault()} onDrop={() => { if (dragFrom != null) move(dragFrom, i); setDragFrom(null); }} onDragEnd={() => setDragFrom(null)} className={cn('flex min-h-[52px] items-center gap-2 py-1', dragFrom === i && 'opacity-50')} > {c.flag} {c.name}
  2. ))}
)}
{!canGo ? {t('compare.builder.needMore', { n: MIN_COMPARE_COUNTRIES - selected.length })} : null} {selected.length ? ( ) : null}
{!canGo && selected.length ?

{t('compare.builder.needMore', { n: MIN_COMPARE_COUNTRIES - selected.length })}

: null}
{/* Presets */}

{t('compare.presets.title')}

{t('compare.presets.sub')}

    {[...COMPARE_GROUP_PRESETS.map((p) => ({ id: p.id, label: t(`compare.preset.${p.id}` as 'compare.preset.g7'), hint: null as string | null, slugs: p.slugs })), ...(peerPreset ? [{ id: 'peers', label: t('compare.preset.peers', { name: 'Canada' }), hint: t('compare.preset.peersHint', { name: 'Canada' }), slugs: peerPreset }] : [])].map((p) => { const members = p.slugs.map((s) => bySlug.get(s)).filter((c): c is CountryLite => !!c); if (members.length < 2) return null; return (
  • m.slug))} className="group min-w-0 flex-1"> {p.label} · {t('compare.presets.count', { n: members.length })} {members.map((m) => ( {m.flag} ))} {p.hint ? {p.hint} : null}
  • ); })}

{t('compare.presets.pairs')}

    {COMPARE_PRESETS.map(([a, b]) => { const ca = bySlug.get(a); const cb = bySlug.get(b); if (!ca || !cb) return null; return (
  • {ca.flag} {ca.name} {t('compare.vs')} {cb.flag} {cb.name}
  • ); })}
setSheet(false)} countries={countries} exclude={exclude} onPick={add} title={t('compare.addCountry')} closeOnPick={false} />
); }