package com.jsjdesigns.poker

import com.jsjdesigns.poker.game.DecisionOffer

/**
 * What the action bar should show for a decision.
 *
 * Kept as a pure function of the offer so it can be unit-tested without a Compose
 * runtime. The UI only renders this; it makes no decisions of its own.
 */
data class ActionButtons(
    val showFold: Boolean,
    val checkOrCallLabel: String,
    /** What calling actually costs: the engine clamps a call to the stack. */
    val effectiveCall: Int,
    val showRaise: Boolean,
    /** False when there is exactly one legal raise size, so a slider is pointless. */
    val showSlider: Boolean,
    val sliderMin: Int,
    val sliderMax: Int,
    /** The amount to submit when the slider is hidden. */
    val fixedRaiseTo: Int,
)

fun buttonsFor(offer: DecisionOffer): ActionButtons {
    // When a stack cannot cover a full min-raise it may still shove; the engine
    // clamps such a raise to maxRaiseTo. Requiring maxRaiseTo > minRaiseTo to show
    // the button hid both that short all-in AND an exact-minimum raise, even
    // though the engine accepts both.
    val shoveOnly = offer.maxRaiseTo <= offer.minRaiseTo
    val low = if (shoveOnly) offer.maxRaiseTo else offer.minRaiseTo
    val high = offer.maxRaiseTo

    // Sourced from the offer, not recomputed: the label, the submitted action and
    // the engine must all agree on one number.
    val effectiveCall = offer.callAmount

    return ActionButtons(
        // Folding a free hand is never correct, so don't invite an accidental muck.
        showFold = !offer.canCheck,
        checkOrCallLabel = when {
            offer.canCheck -> "Check"
            offer.callIsAllIn -> "All in $effectiveCall"
            else -> "Call $effectiveCall"
        },
        effectiveCall = effectiveCall,
        showRaise = offer.canRaise,
        showSlider = high > low,
        sliderMin = low,
        sliderMax = high,
        fixedRaiseTo = low,
    )
}

/** Label for the raise button at [amount]. */
fun raiseLabel(buttons: ActionButtons, amount: Int): String =
    if (amount >= buttons.sliderMax) "All in" else "Raise $amount"
