//
//  BaccaratGameData.swift
//  Baccarat
//
//  Baccarat-specific game data that persists to iCloud.
//

import Foundation
import CasinoKit

/// Persisted data for Baccarat game.
public struct BaccaratGameData: PersistableGameData {
    
    // MARK: - PersistableGameData
    
    public static let gameIdentifier = "baccarat"
    
    public var roundsPlayed: Int {
        roundHistory.count
    }
    
    public static var empty: BaccaratGameData {
        BaccaratGameData(
            balance: 10_000,
            roundHistory: [],
            totalWinnings: 0,
            biggestWin: 0,
            biggestLoss: 0,
            lastModified: Date()
        )
    }
    
    // MARK: - Game Data
    
    /// Current chip balance.
    public var balance: Int
    
    /// History of all rounds played.
    public var roundHistory: [SavedRoundResult]
    
    // MARK: - Lifetime Statistics
    
    /// Total net winnings (can be negative).
    public var totalWinnings: Int
    
    /// Biggest single-round win.
    public var biggestWin: Int
    
    /// Biggest single-round loss (stored as positive number).
    public var biggestLoss: Int
    
    /// Last time data was modified (required by PersistableGameData).
    public var lastModified: Date
    
    // MARK: - Computed Stats
    
    /// Number of Player wins.
    public var playerWins: Int {
        roundHistory.filter { $0.result == "player" }.count
    }
    
    /// Number of Banker wins.
    public var bankerWins: Int {
        roundHistory.filter { $0.result == "banker" }.count
    }
    
    /// Number of Tie games.
    public var tieGames: Int {
        roundHistory.filter { $0.result == "tie" }.count
    }
    
    /// Win rate percentage.
    public var winRate: Double {
        guard roundsPlayed > 0 else { return 0 }
        let wins = roundHistory.filter { $0.netWinnings > 0 }.count
        return Double(wins) / Double(roundsPlayed) * 100
    }
}

/// Codable round result for persistence.
public struct SavedRoundResult: Codable, Identifiable, Sendable {
    public let id: UUID
    public let result: String  // "player", "banker", "tie"
    public let playerValue: Int
    public let bankerValue: Int
    public let playerPair: Bool
    public let bankerPair: Bool
    public let isNatural: Bool
    public let timestamp: Date
    public let netWinnings: Int
    
    public init(
        id: UUID = UUID(),
        result: String,
        playerValue: Int,
        bankerValue: Int,
        playerPair: Bool,
        bankerPair: Bool,
        isNatural: Bool,
        timestamp: Date = Date(),
        netWinnings: Int
    ) {
        self.id = id
        self.result = result
        self.playerValue = playerValue
        self.bankerValue = bankerValue
        self.playerPair = playerPair
        self.bankerPair = bankerPair
        self.isNatural = isNatural
        self.timestamp = timestamp
        self.netWinnings = netWinnings
    }
}

// MARK: - Conversion from RoundResult

extension SavedRoundResult {
    /// Creates a SavedRoundResult from a RoundResult and net winnings.
    init(from roundResult: RoundResult, netWinnings: Int) {
        self.id = roundResult.id
        self.result = roundResult.result.persistenceKey
        self.playerValue = roundResult.playerValue
        self.bankerValue = roundResult.bankerValue
        self.playerPair = roundResult.playerPair
        self.bankerPair = roundResult.bankerPair
        self.isNatural = roundResult.isNatural
        self.timestamp = roundResult.timestamp
        self.netWinnings = netWinnings
    }
}

// MARK: - GameResult Extension

extension GameResult {
    /// String key for persistence.
    var persistenceKey: String {
        switch self {
        case .playerWins: return "player"
        case .bankerWins: return "banker"
        case .tie: return "tie"
        }
    }
    
    /// Creates GameResult from persistence key.
    init?(persistenceKey: String) {
        switch persistenceKey {
        case "player": self = .playerWins
        case "banker": self = .bankerWins
        case "tie": self = .tie
        default: return nil
        }
    }
}

