package com.jsjdesigns.poker

import com.jsjdesigns.poker.game.HandResult

/**
 * Immutable, presentation-ready outcome for one completed hand.
 *
 * This is built from [HandResult], not inferred from the final table snapshot:
 * side pots can produce several winners and a player's net can differ from the
 * amount of any pot they won.
 */
data class HandSummary(
    val handNumber: Int,
    /** Display labels in the engine's winner order; the human seat is always "You". */
    val winnerLabels: List<String>,
    /** Derived from winner seat indices, never from a player-controlled name. */
    val heroWon: Boolean,
    val potSize: Int,
    val heroNet: Int,
    val wentToShowdown: Boolean,
) {
    val title: String
        get() = when {
            winnerLabels.size == 1 && heroWon -> "You win"
            winnerLabels.size == 1 -> "${winnerLabels.single()} wins"
            else -> "${winnerLabels.joinToString(" & ")} win"
        }

    val detail: String
        get() {
            val ending = when {
                heroNet > 0 -> "You won $heroNet"
                heroNet < 0 -> "You lost ${-heroNet}"
                else -> "You broke even"
            }
            val finish = if (wentToShowdown) "Showdown" else "Uncontested"
            return "$finish  •  Pot $potSize  •  $ending"
        }
}

fun handSummaryFor(
    handNumber: Int,
    result: HandResult,
    seatNames: List<String>,
    heroSeat: Int = HERO_SEAT,
): HandSummary {
    require(heroSeat in result.net.indices) { "hero seat is outside the result" }
    require(result.winners.isNotEmpty()) { "a completed hand must have a winner" }
    require(result.winners.all { it in seatNames.indices }) { "winner seat is outside the roster" }

    return HandSummary(
        handNumber = handNumber,
        winnerLabels = result.winners.map { winner ->
            if (winner == heroSeat) "You" else seatNames[winner]
        },
        heroWon = heroSeat in result.winners,
        potSize = result.potSize,
        heroNet = result.net[heroSeat],
        wentToShowdown = result.wentToShowdown,
    )
}
