'use client'; import { TrendingDown, Info } from 'lucide-react'; import type { LeagueConfigFormModel } from '@gridpilot/racing/application'; import Input from '@/components/ui/Input'; import SegmentedControl from '@/components/ui/SegmentedControl'; interface LeagueDropSectionProps { form: LeagueConfigFormModel; onChange?: (form: LeagueConfigFormModel) => void; readOnly?: boolean; } export function LeagueDropSection({ form, onChange, readOnly, }: LeagueDropSectionProps) { const disabled = readOnly || !onChange; const dropPolicy = form.dropPolicy; const updateDropPolicy = ( patch: Partial, ) => { if (!onChange) return; onChange({ ...form, dropPolicy: { ...dropPolicy, ...patch, }, }); }; const handleStrategyChange = ( strategy: LeagueConfigFormModel['dropPolicy']['strategy'], ) => { if (strategy === 'none') { updateDropPolicy({ strategy: 'none', n: undefined }); } else if (strategy === 'bestNResults') { const n = dropPolicy.n ?? 6; updateDropPolicy({ strategy: 'bestNResults', n }); } else if (strategy === 'dropWorstN') { const n = dropPolicy.n ?? 2; updateDropPolicy({ strategy: 'dropWorstN', n }); } }; const handleNChange = (value: string) => { const parsed = parseInt(value, 10); updateDropPolicy({ n: Number.isNaN(parsed) || parsed <= 0 ? undefined : parsed, }); }; const getSuggestedN = () => { const rounds = form.timings.roundsPlanned; if (!rounds || rounds <= 0) return null; if (dropPolicy.strategy === 'bestNResults') { // Suggest keeping 70-80% of rounds const suggestion = Math.max(1, Math.floor(rounds * 0.75)); return { value: suggestion, explanation: `Keep best ${suggestion} of ${rounds} rounds (75%)` }; } else if (dropPolicy.strategy === 'dropWorstN') { // Suggest dropping 1-2 rounds for every 8-10 rounds const suggestion = Math.max(1, Math.floor(rounds / 8)); return { value: suggestion, explanation: `Drop worst ${suggestion} of ${rounds} rounds` }; } return null; }; const computeSummary = () => { if (dropPolicy.strategy === 'none') { return 'All results will count towards the championship.'; } if (dropPolicy.strategy === 'bestNResults') { const n = dropPolicy.n; if (typeof n === 'number' && n > 0) { return `Best ${n} results will count; others are ignored.`; } return 'Best N results will count; others are ignored.'; } if (dropPolicy.strategy === 'dropWorstN') { const n = dropPolicy.n; if (typeof n === 'number' && n > 0) { return `Worst ${n} results will be dropped from the standings.`; } return 'Worst N results will be dropped from the standings.'; } return 'All results will count towards the championship.'; }; const currentStrategyValue = dropPolicy.strategy === 'none' ? 'all' : dropPolicy.strategy === 'bestNResults' ? 'bestN' : 'dropWorstN'; const suggestedN = getSuggestedN(); return (

Drop rule

Protect drivers from bad races by dropping worst results or counting only the best ones

{ if (disabled) return; if (value === 'all') { handleStrategyChange('none'); } else if (value === 'bestN') { handleStrategyChange('bestNResults'); } else if (value === 'dropWorstN') { handleStrategyChange('dropWorstN'); } }} /> {dropPolicy.strategy === 'none' && (

All count: Every race result affects the championship. Best for shorter seasons or when consistency is key.

)}
{(dropPolicy.strategy === 'bestNResults' || dropPolicy.strategy === 'dropWorstN') && (
{suggestedN && (

Suggested: {suggestedN.explanation}

)}
0 ? String(dropPolicy.n) : '' } onChange={(e) => handleNChange(e.target.value)} disabled={disabled} min={1} className="max-w-[140px]" />

{dropPolicy.strategy === 'bestNResults' ? 'Only your best N results will count towards the championship. Great for long seasons.' : 'Your worst N results will be excluded from the championship. Helps forgive bad days.'}

)}
{computeSummary()}
); }