import { FEE_SCHEDULE_AS_OF, type FeeSchedule } from '@rareindex/valuation'; import { fmtMoney, fmtPct, cn } from '@/lib/format'; import { Badge, Table, th, td, tdNum } from '@/components/ui/primitives'; export function FeeConfidenceBadge({ confidence, className }: { confidence: FeeSchedule['confidence'] | 'unknown'; className?: string }) { const map: Record = { published: { tone: 'gain', label: 'Published', title: `Taken from the house's published terms as of ${FEE_SCHEDULE_AS_OF}` }, approximate: { tone: 'index', label: '≈ Approximate', title: 'Widely reported schedule not re-verified against the current terms — every all-in figure built on it is labelled as an estimate' }, none: { tone: 'neutral', label: 'No buyer premium', title: 'The house bills the hammer price; the seller pays the commission' }, default: { tone: 'alert', label: 'Default 22 %', title: 'House not on file — a typical 22 % premium is applied and labelled' }, unknown: { tone: 'alert', label: 'Unknown', title: 'No schedule on file' }, }; const m = map[confidence] ?? map.unknown!; return ( {m.label} ); } /** Buyer's premium schedule of one house (§35): marginal tiers, minimum/maximum, fixed fee, confidence and source. */ export function FeeScheduleTable({ schedule, className }: { schedule: FeeSchedule; className?: string }) { const cur = schedule.currency; const tiers = schedule.tiers.map((t, i) => ({ from: i === 0 ? 0 : (schedule.tiers[i - 1]!.upTo ?? 0), to: t.upTo, rate: t.rate })); return (
{tiers.map((t, i) => ( ))} {schedule.minimum !== undefined ? ( ) : null} {schedule.maximum !== undefined ? ( ) : null} {schedule.fixedFee !== undefined ? ( ) : null}
Hammer price ({cur}) Buyer's premium
{t.to === null ? `above ${fmtMoney(t.from, cur)}` : t.from === 0 ? `up to ${fmtMoney(t.to, cur)}` : `${fmtMoney(t.from, cur)} – ${fmtMoney(t.to, cur)}`} {fmtPct(t.rate, t.rate * 100 % 1 ? 1 : 0, false)}
Minimum premium {fmtMoney(schedule.minimum, cur)}
Maximum premium {fmtMoney(schedule.maximum, cur)}
Fixed fee per lot {fmtMoney(schedule.fixedFee, cur)}

Schedule as of {FEE_SCHEDULE_AS_OF}.{schedule.note ? ` ${schedule.note}` : ''} VAT or sales tax on the premium, import duties and shipping are not included. {schedule.source ? ( <> {' '} Source ↗ ) : null}

); } /** One-line summary of a schedule for lists: "27 % → 15 % (3 tiers)" or "20 %". */ export function feeScheduleSummary(s: FeeSchedule): string { const rates = s.tiers.map((t) => fmtPct(t.rate, t.rate * 100 % 1 ? 1 : 0, false)); const base = rates.length === 1 ? rates[0]! : `${rates[0]} → ${rates.at(-1)} (${rates.length} tiers)`; const extras = [s.minimum !== undefined ? `min ${fmtMoney(s.minimum, s.currency)}` : null, s.maximum !== undefined ? `cap ${fmtMoney(s.maximum, s.currency)}` : null, s.fixedFee !== undefined ? `+ ${fmtMoney(s.fixedFee, s.currency)}/lot` : null].filter(Boolean); return extras.length ? `${base} · ${extras.join(' · ')}` : base; }