import { useState, useEffect, useRef } from "react"; import { Check, Info, ChevronDown } from "lucide-react"; import { toast } from "sonner"; import { Label } from "~/components/ui/label"; import { Popover, PopoverContent, PopoverTrigger } from "~/components/ui/popover"; type AutodraftMode = "next_pick" | "while_on"; // 4 visible states map to isEnabled + mode + queueOnly: // "off" → isEnabled: false // "next_queue" → isEnabled: true, mode: "next_pick", queueOnly: true // "all_queue" → isEnabled: true, mode: "while_on", queueOnly: true // "all_picks" → isEnabled: true, mode: "while_on", queueOnly: false type AutodraftState = "off" | "next_queue" | "all_queue" | "all_picks"; type OptionConfig = { label: string; desc: string; isEnabled: boolean; mode: AutodraftMode; queueOnly: boolean; }; // Record ensures all AutodraftState values are covered — no runtime find() needed const OPTIONS: Record = { off: { label: "Off", desc: "You pick manually every round.", isEnabled: false, mode: "next_pick", queueOnly: false, }, next_queue: { label: "Next in Queue", desc: "Autodrafts your next pick from your queue, then turns off.", isEnabled: true, mode: "next_pick", queueOnly: true, }, all_queue: { label: "All in Queue", desc: "Keeps autodrafting from your queue until it runs out, then turns off automatically.", isEnabled: true, mode: "while_on", queueOnly: true, }, all_picks: { label: "All Picks", desc: "Keeps autodrafting all your picks. Uses your queue first, then falls back to the highest-ranked undrafted player.", isEnabled: true, mode: "while_on", queueOnly: false, }, }; const OPTION_ORDER: AutodraftState[] = ["off", "next_queue", "all_queue", "all_picks"]; // border-l-[3px] is applied to ALL options (transparent when inactive) so the // content never shifts when the active border color is applied. function getButtonClassName(state: AutodraftState, isActive: boolean): string { if (!isActive) { return "border-l-[3px] border-l-transparent text-muted-foreground hover:bg-muted/40"; } if (state === "off") { return "border-l-[3px] border-l-muted-foreground/50 text-foreground"; } return "border-l-[3px] border-l-electric bg-electric text-background"; } function getCheckClassName(state: AutodraftState): string { if (state === "off") return "text-muted-foreground"; return "text-background"; } function toAutodraftState( isEnabled: boolean, mode: AutodraftMode, queueOnly: boolean ): AutodraftState { if (!isEnabled) return "off"; if (mode === "next_pick") return "next_queue"; return queueOnly ? "all_queue" : "all_picks"; } export function getAutodraftLabel( isEnabled: boolean, mode: AutodraftMode, queueOnly: boolean ): string { return OPTIONS[toAutodraftState(isEnabled, mode, queueOnly)].label; } interface CompactAutodraftBadgeProps { isEnabled: boolean; mode: AutodraftMode; queueOnly: boolean; isMyTurn: boolean; showChevron?: boolean; } export function CompactAutodraftBadge({ isEnabled, mode, queueOnly, isMyTurn, showChevron = false, }: CompactAutodraftBadgeProps) { const state = toAutodraftState(isEnabled, mode, queueOnly); const { label } = OPTIONS[state]; const isOff = state === "off"; return (
Autodraft: {label} {showChevron && } {isMyTurn && ( Your turn! )}
); } interface AutodraftBadgeWithPopoverProps { seasonId: string; teamId: string; isEnabled: boolean; mode: AutodraftMode; queueOnly: boolean; isMyTurn: boolean; onUpdate: (isEnabled: boolean, mode: AutodraftMode, queueOnly: boolean) => void; } function AutodraftOptions({ seasonId, teamId, isEnabled, mode, queueOnly, isMyTurn, onUpdate, }: Omit & { seasonId: string; teamId: string; }) { const [localState, setLocalState] = useState( toAutodraftState(isEnabled, mode, queueOnly) ); const abortRef = useRef(null); useEffect(() => { setLocalState(toAutodraftState(isEnabled, mode, queueOnly)); }, [isEnabled, mode, queueOnly]); const sendUpdate = async (newState: AutodraftState) => { abortRef.current?.abort(); abortRef.current = new AbortController(); const option = OPTIONS[newState]; try { const formData = new FormData(); formData.append("seasonId", seasonId); formData.append("teamId", teamId); formData.append("isEnabled", option.isEnabled.toString()); formData.append("mode", option.mode); formData.append("queueOnly", option.queueOnly.toString()); const response = await fetch("/api/autodraft/update", { method: "POST", body: formData, signal: abortRef.current.signal, }); if (response.ok) { onUpdate(option.isEnabled, option.mode, option.queueOnly); toast.success( option.isEnabled ? `Autodraft set to "${option.label}"` : "Autodraft turned off" ); } else { setLocalState(toAutodraftState(isEnabled, mode, queueOnly)); toast.error("Failed to save autodraft settings"); } } catch (error) { if (error instanceof Error && error.name === "AbortError") return; setLocalState(toAutodraftState(isEnabled, mode, queueOnly)); toast.error("Failed to save autodraft settings"); } }; const handleStateChange = (newState: AutodraftState) => { if (newState === localState || isMyTurn) return; setLocalState(newState); sendUpdate(newState); }; const isDisabled = isMyTurn; return (
{OPTION_ORDER.map((state) => { const { label } = OPTIONS[state]; const isActive = localState === state; return ( ); })} {isMyTurn && (

You're on the clock!

)}
); } export function AutodraftBadgeWithPopover({ seasonId, teamId, isEnabled, mode, queueOnly, isMyTurn, onUpdate, }: AutodraftBadgeWithPopoverProps) { const [open, setOpen] = useState(false); return (

Autodraft Options

{OPTION_ORDER.map((state) => { const { label, desc } = OPTIONS[state]; return (

{label}

{desc}

); })}
); } interface AutodraftSettingsProps { seasonId: string; teamId: string; isEnabled: boolean; mode: AutodraftMode; queueOnly: boolean; isMyTurn: boolean; onUpdate: (isEnabled: boolean, mode: AutodraftMode, queueOnly: boolean) => void; } export function AutodraftSettings({ seasonId, teamId, isEnabled, mode, queueOnly, isMyTurn, onUpdate, }: AutodraftSettingsProps) { const [localState, setLocalState] = useState( toAutodraftState(isEnabled, mode, queueOnly) ); // Holds the abort controller for any in-flight save so rapid selections // cancel the previous request rather than racing to update the server. const abortRef = useRef(null); // Sync local state with props when they change (from socket events) useEffect(() => { setLocalState(toAutodraftState(isEnabled, mode, queueOnly)); }, [isEnabled, mode, queueOnly]); const sendUpdate = async (newState: AutodraftState) => { // Cancel any in-flight request before starting a new one abortRef.current?.abort(); abortRef.current = new AbortController(); const option = OPTIONS[newState]; try { const formData = new FormData(); formData.append("seasonId", seasonId); formData.append("teamId", teamId); formData.append("isEnabled", option.isEnabled.toString()); formData.append("mode", option.mode); formData.append("queueOnly", option.queueOnly.toString()); const response = await fetch("/api/autodraft/update", { method: "POST", body: formData, signal: abortRef.current.signal, }); if (response.ok) { onUpdate(option.isEnabled, option.mode, option.queueOnly); toast.success( option.isEnabled ? `Autodraft set to "${option.label}"` : "Autodraft turned off" ); } else { setLocalState(toAutodraftState(isEnabled, mode, queueOnly)); toast.error("Failed to save autodraft settings"); } } catch (error) { // Ignore cancellations — a newer selection has already taken over if (error instanceof Error && error.name === "AbortError") return; setLocalState(toAutodraftState(isEnabled, mode, queueOnly)); toast.error("Failed to save autodraft settings"); } }; const handleStateChange = (newState: AutodraftState) => { if (newState === localState || isMyTurn) return; setLocalState(newState); sendUpdate(newState); }; const isDisabled = isMyTurn; return (
{/* Header with info icon inline */}

Autodraft Options

{OPTION_ORDER.map((state) => { const { label, desc } = OPTIONS[state]; return (

{label}

{desc}

); })}
{OPTION_ORDER.map((state) => { const { label } = OPTIONS[state]; const isActive = localState === state; return ( ); })}
{isMyTurn && (

You're on the clock!

)}
); }