'use client'; import { useId, useState } from 'react'; import type { Action, GameView } from '@/game/engine'; import { location, territory } from '@/game/board'; import { Button } from './ui/button'; import { Input } from './ui/input'; const bounded = (value: number, min: number, max: number) => Math.max(min, Math.min(max, Number.isSafeInteger(value) ? value : min)); /** Mounted with the Ambassador event key so an earlier shipment draft cannot carry over. */ export function AmbassadorShipment({ game, act, busy, }: { game: GameView; act: (action: Action) => void; busy: boolean; }) { const id = useId(); const [destinationKey, setDestinationKey] = useState(''); const [count, setCount] = useState(null); const [eliteCount, setEliteCount] = useState(0); const entry = game.ambassadorEntry; if ( entry?.stage !== 'ship' || entry.beneficiary !== game.me || game.decision?.kind !== 'ecazAmbassador' || game.decision.player !== game.me || !entry.shipment ) return null; const me = game.players.find((p) => p.id === game.me)!; const shipment = entry.shipment; const destination = shipment.destinations.find( (d) => location(d.territory, d.sector) === destinationKey, ) ?? shipment.destinations.find((d) => !d.blocked) ?? shipment.destinations[0]; const maximum = Math.min( shipment.maximum, me.reserves, destination?.maximum ?? shipment.maximum, ); const amount = maximum ? bounded(count ?? maximum, 1, maximum) : 0; const minimumElite = Math.max( 0, amount - (me.reserves - shipment.eliteReserves), ); const maximumElite = Math.min(amount, shipment.eliteReserves); const elite = bounded(eliteCount, minimumElite, maximumElite); const reason = !amount ? 'You have no reserve forces available for this shipment.' : !destination ? 'No shipment destination is currently available.' : destination.blocked; const territories = [ ...new Set(shipment.destinations.map((d) => d.territory)), ]; return (

Send up to four of your reserve forces for free, or send no forces. This does not spend your ordinary shipment or movement. The Ambassador has already been triggered.

{shipment.eliteReserves > 0 && ( )} {destination?.advisors && (

These forces join your advisors.

)}

Selected: {amount} physical forces, including {elite} elites. Cost: 0 spice.

No-Field substitution for this effect remains unfinished.

{reason && (

{reason}

)}
); }