//
//  Card.swift
//  CasinoKit
//
//  A playing card model with suit, rank, and value calculations.
//

import Foundation

/// Represents the four suits in a standard deck of cards.
public enum Suit: String, CaseIterable, Identifiable, Sendable {
    case hearts = "♥"
    case diamonds = "♦"
    case clubs = "♣"
    case spades = "♠"
    
    public var id: String { rawValue }
    
    /// Whether this suit is red (hearts or diamonds).
    public var isRed: Bool {
        self == .hearts || self == .diamonds
    }
    
    /// Accessibility name for VoiceOver.
    public var accessibilityName: String {
        switch self {
        case .hearts: return String(localized: "Hearts", bundle: .module)
        case .diamonds: return String(localized: "Diamonds", bundle: .module)
        case .clubs: return String(localized: "Clubs", bundle: .module)
        case .spades: return String(localized: "Spades", bundle: .module)
        }
    }
}

/// Represents the rank of a card from Ace through King.
public enum Rank: Int, CaseIterable, Identifiable, Sendable {
    case ace = 1
    case two = 2
    case three = 3
    case four = 4
    case five = 5
    case six = 6
    case seven = 7
    case eight = 8
    case nine = 9
    case ten = 10
    case jack = 11
    case queen = 12
    case king = 13
    
    public var id: Int { rawValue }
    
    /// The display symbol for this rank.
    public var symbol: String {
        switch self {
        case .ace: return "A"
        case .jack: return "J"
        case .queen: return "Q"
        case .king: return "K"
        default: return String(rawValue)
        }
    }
    
    /// The standard point value (Ace = 1, 2-10 = face value, J/Q/K = 10).
    public var standardValue: Int {
        switch self {
        case .ace: return 1
        case .jack, .queen, .king: return 10
        default: return rawValue
        }
    }
    
    /// The baccarat point value (Ace = 1, 2-9 = face value, 10/J/Q/K = 0).
    public var baccaratValue: Int {
        switch self {
        case .ace: return 1
        case .two, .three, .four, .five, .six, .seven, .eight, .nine:
            return rawValue
        case .ten, .jack, .queen, .king:
            return 0
        }
    }
    
    /// The blackjack value (Ace = 1 or 11, 2-10 = face value, J/Q/K = 10).
    /// Note: Ace flexibility (1 or 11) should be handled by game logic.
    public var blackjackValue: Int {
        switch self {
        case .ace: return 11 // Game logic should handle soft/hard hands
        case .jack, .queen, .king: return 10
        default: return rawValue
        }
    }
    
    /// Accessibility name for VoiceOver.
    public var accessibilityName: String {
        switch self {
        case .ace: return String(localized: "Ace", bundle: .module)
        case .two: return String(localized: "Two", bundle: .module)
        case .three: return String(localized: "Three", bundle: .module)
        case .four: return String(localized: "Four", bundle: .module)
        case .five: return String(localized: "Five", bundle: .module)
        case .six: return String(localized: "Six", bundle: .module)
        case .seven: return String(localized: "Seven", bundle: .module)
        case .eight: return String(localized: "Eight", bundle: .module)
        case .nine: return String(localized: "Nine", bundle: .module)
        case .ten: return String(localized: "Ten", bundle: .module)
        case .jack: return String(localized: "Jack", bundle: .module)
        case .queen: return String(localized: "Queen", bundle: .module)
        case .king: return String(localized: "King", bundle: .module)
        }
    }
}

/// Represents a single playing card with a suit and rank.
public struct Card: Identifiable, Equatable, Sendable {
    public let id: UUID
    public let suit: Suit
    public let rank: Rank
    
    public init(suit: Suit, rank: Rank, id: UUID = UUID()) {
        self.id = id
        self.suit = suit
        self.rank = rank
    }
    
    /// The baccarat point value of this card.
    public var baccaratValue: Int {
        rank.baccaratValue
    }
    
    /// The blackjack value of this card.
    public var blackjackValue: Int {
        rank.blackjackValue
    }
    
    /// Display string showing rank and suit together.
    public var display: String {
        "\(rank.symbol)\(suit.rawValue)"
    }
    
    /// Accessibility description for VoiceOver.
    public var accessibilityDescription: String {
        "\(rank.accessibilityName) of \(suit.accessibilityName)"
    }
    
    /// The PDF page index (0-51) for this card.
    /// PDF order: Spades (0-12), Hearts (13-25), Clubs (26-38), Diamonds (39-51)
    /// Each suit: 2,3,4,5,6,7,8,9,10,J,Q,K,A
    public var pdfIndex: Int {
        let suitOffset: Int
        switch suit {
        case .spades: suitOffset = 0
        case .hearts: suitOffset = 13
        case .clubs: suitOffset = 26
        case .diamonds: suitOffset = 39
        }
        // PDF order: 2=0, 3=1, ..., 10=8, J=9, Q=10, K=11, A=12
        let rankOffset: Int
        switch rank {
        case .ace: rankOffset = 12  // Ace is last in PDF
        default: rankOffset = rank.rawValue - 2  // 2=0, 3=1, etc.
        }
        return suitOffset + rankOffset
    }
}

