'use client'; import { useId, useState } from 'react'; import type { Player } from '@/game/engine'; import { eliteRevivalRemaining, paidForceRevivalCost } from '@/game/revival'; /** Public alliance members only; the engine remains the legality authority. */ export type CoalitionEmperorAlly = Pick; export type CoalitionEmperorAidAction = | { type: 'emperorGift'; target: string; amount: number } | { type: 'emperorRevival'; target: string; amount: number; elite: number }; function positiveInteger(raw: string): number | null { if (!/^[1-9]\d*$/.test(raw)) return null; const value = Number(raw); return Number.isSafeInteger(value) ? value : null; } /** Render for an Emperor in a staged group alliance; pair controls stay separate. */ export function CoalitionEmperorAid({ allies, phase, advanced, availableSpice, emperorExtra, revivalOrderHead, busy = false, act }: { allies: readonly CoalitionEmperorAlly[]; phase: number; advanced: boolean; /** Spice not committed to coalition pledges or other obligations. */ availableSpice: number; emperorExtra: Readonly>; revivalOrderHead?: string | null; busy?: boolean; act: (action: CoalitionEmperorAidAction) => void; }) { const id = useId(); const [giftTarget, setGiftTarget] = useState(''); const [giftRaw, setGiftRaw] = useState('1'); const [revivalTarget, setRevivalTarget] = useState(''); const [revivalRaw, setRevivalRaw] = useState('1'); const [eliteRaw, setEliteRaw] = useState('0'); const giftAlly = allies.find(ally => ally.id === giftTarget); const revivalAlly = allies.find(ally => ally.id === revivalTarget); const gift = positiveInteger(giftRaw); const amount = positiveInteger(revivalRaw); const elite = /^(0|[1-9]\d*)$/.test(eliteRaw) && Number.isSafeInteger(Number(eliteRaw)) ? Number(eliteRaw) : null; const maximum = revivalAlly ? Math.max(0, Math.min( 3 - (emperorExtra[revivalAlly.id] ?? 0), revivalAlly.tanks, Math.floor(availableSpice / 2), )) : 0; const cost = revivalAlly && amount && elite !== null ? paidForceRevivalCost(revivalAlly, amount, elite) : null; const eliteTanks = revivalAlly?.elites?.tanks ?? 0; const legalElite = revivalAlly && amount && elite !== null && elite <= Math.min(amount, eliteRevivalRemaining(revivalAlly, advanced)) && amount - elite <= revivalAlly.tanks - eliteTanks; const canGift = !!giftAlly && gift !== null && gift <= availableSpice && !busy; const canRevive = phase === 4 && !!revivalAlly && amount !== null && amount <= maximum && legalElite && cost !== null && cost <= availableSpice && (!revivalOrderHead || revivalOrderHead === revivalAlly.id) && !busy; return

Emperor alliance aid

Choose which ally receives your aid. Spice and revivals take effect after the Karama response.

setGiftRaw(event.target.value)} /> {phase === 4 &&
{revivalAlly && <>

{revivalAlly.name} has {revivalAlly.tanks} forces in the tanks and can receive up to {maximum} extra revivals now.

{revivalOrderHead && revivalOrderHead !== revivalAlly.id &&

Wait for this ally’s revival turn.

} setRevivalRaw(event.target.value)} /> {revivalAlly.elites && <> setEliteRaw(event.target.value)} /> } {cost !== null &&

You pay {cost} spice. This uses {revivalAlly.name}’s extra-revival allowance.

} }
}
; }