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

import Foundation
import CasinoKit

/// Persisted data for Baccarat game.
public struct BaccaratGameData: PersistableGameData, SessionPersistable {
    
    // MARK: - PersistableGameData
    
    public static let gameIdentifier = "baccarat"
    
    public var roundsPlayed: Int {
        // Total rounds from all sessions
        let historicalRounds = sessionHistory.reduce(0) { $0 + $1.roundsPlayed }
        let currentRounds = currentSession?.roundsPlayed ?? 0
        return historicalRounds + currentRounds
    }
    
    public static var empty: BaccaratGameData {
        BaccaratGameData(
            lastModified: Date(),
            balance: 1_000,
            currentSession: nil,
            sessionHistory: [],
            currentSessionRoundHistory: [],
            sessionRoundHistories: [:]
        )
    }
    
    // MARK: - Game Data
    
    /// Last time data was modified (required by PersistableGameData).
    public var lastModified: Date
    
    /// Current chip balance.
    public var balance: Int
    
    /// The currently active session (nil if no session started).
    public var currentSession: BaccaratSession?
    
    /// History of completed sessions.
    public var sessionHistory: [BaccaratSession]
    
    /// Round history for the current session (for road map display).
    /// This is cleared when a new session starts.
    public var currentSessionRoundHistory: [SavedRoundResult]
    
    /// Round histories for completed sessions (keyed by session ID string).
    /// Used to display road maps when viewing historical sessions.
    public var sessionRoundHistories: [String: [SavedRoundResult]]
}

/// Codable round result for persistence (for road map display).
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 init(
        id: UUID = UUID(),
        result: String,
        playerValue: Int,
        bankerValue: Int,
        playerPair: Bool,
        bankerPair: Bool,
        isNatural: Bool,
        timestamp: Date = Date()
    ) {
        self.id = id
        self.result = result
        self.playerValue = playerValue
        self.bankerValue = bankerValue
        self.playerPair = playerPair
        self.bankerPair = bankerPair
        self.isNatural = isNatural
        self.timestamp = timestamp
    }
}

// MARK: - Conversion from RoundResult

extension SavedRoundResult {
    /// Creates a SavedRoundResult from a RoundResult.
    init(from roundResult: RoundResult) {
        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
    }
    
    /// Converts back to RoundResult for display.
    func toRoundResult() -> RoundResult? {
        guard let gameResult = GameResult(persistenceKey: result) else { return nil }
        return RoundResult(
            result: gameResult,
            playerValue: playerValue,
            bankerValue: bankerValue,
            playerPair: playerPair,
            bankerPair: bankerPair
        )
    }
}

// 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
        }
    }
}
