'use client'; import type { LeagueConfigFormModel } from '@/lib/types/LeagueConfigFormModel'; import { Heading } from '@/ui/Heading'; import { Icon } from '@/ui/Icon'; import { Text } from '@/ui/Text'; import { Box } from '@/ui/Box'; import { Group } from '@/ui/Group'; import { Stack } from '@/ui/Stack'; import { Surface } from '@/ui/Surface'; import { InfoFlyout } from '@/components/shared/InfoFlyout'; import { Stepper } from '@/ui/Stepper'; import { Button } from '@/ui/Button'; import { IconButton } from '@/ui/IconButton'; import { Check, HelpCircle, TrendingDown, Zap } from 'lucide-react'; import React, { useRef, useState } from 'react'; interface LeagueDropSectionProps { form: LeagueConfigFormModel; onChange?: (form: LeagueConfigFormModel) => void; readOnly?: boolean; } type DropStrategy = 'none' | 'bestNResults' | 'dropWorstN'; const DROP_OPTIONS: Array<{ value: DropStrategy; label: string; emoji: string; description: string; defaultN?: number; }> = [ { value: 'none', label: 'All count', emoji: '✓', description: 'Every race counts', }, { value: 'bestNResults', label: 'Best N', emoji: '🏆', description: 'Only best results', defaultN: 6, }, { value: 'dropWorstN', label: 'Drop worst', emoji: '🗑️', description: 'Exclude worst races', defaultN: 2, }, ]; export function LeagueDropSection({ form, onChange, readOnly, }: LeagueDropSectionProps) { const disabled = readOnly || !onChange; const dropPolicy = form.dropPolicy || { strategy: 'none' as const }; const [showDropFlyout, setShowDropFlyout] = useState(false); const dropInfoRef = useRef(null!); const handleStrategyChange = (strategy: DropStrategy) => { if (disabled || !onChange) return; const option = DROP_OPTIONS.find((o) => o.value === strategy); const next: LeagueConfigFormModel = { ...form, dropPolicy: strategy === 'none' ? { strategy, } : { strategy, n: dropPolicy.n ?? option?.defaultN ?? 1, }, }; onChange(next); }; const handleNChange = (newValue: number) => { if (disabled || !onChange || dropPolicy.strategy === 'none') return; onChange({ ...form, dropPolicy: { ...dropPolicy, n: newValue, }, }); }; const needsN = dropPolicy.strategy !== 'none'; return ( {/* Section header */} Drop Rules setShowDropFlyout(true)} title="Help" /> Protect from bad races setShowDropFlyout(false)} title="Drop Rules Explained" anchorRef={dropInfoRef} > Drop rules allow drivers to exclude their worst results from championship calculations. This protects against mechanical failures, bad luck, or occasional poor performances. {/* Strategy buttons + N stepper inline */} {DROP_OPTIONS.map((option) => { const isSelected = dropPolicy.strategy === option.value; return ( ); })} {needsN && ( )} {/* Explanation text */} {dropPolicy.strategy === 'none' && 'Every race result affects the championship standings.'} {dropPolicy.strategy === 'bestNResults' && `Only your best ${dropPolicy.n ?? 1} results will count.`} {dropPolicy.strategy === 'dropWorstN' && `Your worst ${dropPolicy.n ?? 1} results will be excluded.`} ); }