//
//  PlayerHandView.swift
//  Blackjack
//
//  Displays a single player hand with label, value badge, cards, and bet.
//

import SwiftUI
import CasinoKit

/// Displays a single player hand with cards, value, and result.
struct PlayerHandView: View {
    let hand: BlackjackHand
    let isActive: Bool
    let showCardCount: Bool
    let showAnimations: Bool
    let dealingSpeed: Double
    let handNumber: Int?
    let cardWidth: CGFloat
    let cardSpacing: CGFloat
    
    /// Number of cards that have completed their animation
    let visibleCardCount: Int
    
    /// Current hint to display on this hand.
    let currentHint: String?
    
    /// Whether the hint toast should be visible.
    let showHintToast: Bool
    
    @ScaledMetric(relativeTo: .headline) private var labelFontSize: CGFloat = Design.Size.handLabelFontSize
    @ScaledMetric(relativeTo: .caption) private var handNumberSize: CGFloat = Design.Size.handNumberFontSize
    @ScaledMetric(relativeTo: .body) private var iconSize: CGFloat = Design.Size.handIconSize
    @ScaledMetric(relativeTo: .body) private var hintPaddingH: CGFloat = Design.Size.hintPaddingH
    @ScaledMetric(relativeTo: .body) private var hintPaddingV: CGFloat = Design.Size.hintPaddingV
    
    /// The title to display (PLAYER or Hand #).
    private var displayTitle: String {
        if let number = handNumber {
            return String(localized: "Hand \(number)")
        }
        return String(localized: "PLAYER")
    }
    
    /// The badge color (active hands get highlight color).
    private var badgeColor: Color {
        isActive ? Color.Hand.active : Color.Hand.player
    }
    
    /// Calculates display info for visible cards using shared BlackjackHand logic.
    private var visibleCardsDisplayInfo: (text: String, value: Int, isBusted: Bool)? {
        guard !hand.cards.isEmpty else { return nil }
        
        let visibleCards = Array(hand.cards.prefix(visibleCardCount))
        guard !visibleCards.isEmpty else { return nil }
        
        // Use shared static methods for value calculation
        let (hardValue, softValue) = BlackjackHand.calculateValues(for: visibleCards)
        let displayValue = BlackjackHand.bestValue(for: visibleCards)
        let hasSoftAce = BlackjackHand.hasSoftAce(for: visibleCards)
        let isBusted = hardValue > 21
        
        // Show value like hand.valueDisplay does (e.g., "8/18" for soft hands)
        // When soft value is 21, there's no ambiguity - just show 21
        let valueText: String
        if softValue == 21 {
            valueText = "21"
        } else if hasSoftAce {
            valueText = "\(hardValue)/\(softValue)"
        } else {
            valueText = "\(displayValue)"
        }
        
        return (valueText, displayValue, isBusted)
    }
    
    var body: some View {
        VStack(spacing: Design.Spacing.small) {
            // Label and value badge at TOP (consistent with dealer)
            HandLabelView(
                title: displayTitle,
                valueText: visibleCardsDisplayInfo?.text,
                badgeColor: badgeColor
            )
            .animation(nil, value: visibleCardCount)
            
            // Cards with container
            CardStackView.player(
                cards: hand.cards,
                cardWidth: cardWidth,
                cardSpacing: cardSpacing,
                showAnimations: showAnimations,
                dealingSpeed: dealingSpeed,
                showCardCount: showCardCount
            )
            .padding(.horizontal, Design.Spacing.medium)
            .padding(.vertical, Design.Spacing.medium)
            .background(
                RoundedRectangle(cornerRadius: Design.CornerRadius.medium)
                    .fill(Color.Table.feltDark.opacity(Design.Opacity.light))
                    .overlay(
                        RoundedRectangle(cornerRadius: Design.CornerRadius.medium)
                            .strokeBorder(
                                isActive ? Color.Hand.active : Color.white.opacity(Design.Opacity.hint),
                                lineWidth: isActive ? Design.LineWidth.thick : Design.LineWidth.thin
                            )
                    )
            )
            .overlay {
                // Result badge - centered on cards (takes priority over hint)
                if let result = hand.result {
                    Text(result.displayText)
                        .font(.system(size: labelFontSize, weight: .black))
                        .foregroundStyle(.white)
                        .padding(.horizontal, hintPaddingH)
                        .padding(.vertical, hintPaddingV)
                        .background(
                            Capsule()
                                .fill(result.color)
                                .shadow(color: .black.opacity(Design.Opacity.medium), radius: Design.Shadow.radiusMedium)
                        )
                        .transition(.scale.combined(with: .opacity))
                } else if showHintToast, let hint = currentHint {
                    // Hint toast - centered on active hand (only when no result)
                    HintView(hint: hint)
                        .transition(.scale.combined(with: .opacity))
                }
            }
            .contentShape(Rectangle())
            .animation(.easeInOut(duration: Design.Animation.quick), value: isActive)
            .animation(.spring(duration: Design.Animation.springDuration), value: hand.result != nil)
            
            // Bet amount and doubled down indicator
            if hand.bet > 0 || hand.isDoubledDown {
                HStack(spacing: Design.Spacing.small) {
                    if hand.bet > 0 {
                        HStack(spacing: Design.Spacing.xSmall) {
                            Image(systemName: "dollarsign.circle.fill")
                                .font(.system(size: iconSize))
                                .foregroundStyle(.yellow)
                            Text("\(hand.bet * (hand.isDoubledDown ? 2 : 1))")
                                .font(.system(size: handNumberSize, weight: .bold, design: .rounded))
                                .foregroundStyle(.yellow)
                        }
                    }
                    
                    if hand.isDoubledDown {
                        Image(systemName: "xmark.circle.fill")
                            .font(.system(size: iconSize))
                            .foregroundStyle(.purple)
                    }
                }
            }
        }
        .accessibilityElement(children: .ignore)
        .accessibilityLabel(playerAccessibilityLabel)
    }
    
    // MARK: - Computed Properties
    
    private var playerAccessibilityLabel: String {
        let cardsDescription = hand.cards.map { $0.accessibilityDescription }.joined(separator: ", ")
        var label = String(localized: "Player hand: \(cardsDescription). Value: \(hand.valueDisplay)")
        if let result = hand.result {
            label += ". \(result.displayText)"
        }
        return label
    }
}

// MARK: - Previews

#Preview("Empty Hand") {
    ZStack {
        Color.Table.felt.ignoresSafeArea()
        PlayerHandView(
            hand: BlackjackHand(),
            isActive: true,
            showCardCount: false,
            showAnimations: true,
            dealingSpeed: 1.0,
            handNumber: nil,
            cardWidth: 60,
            cardSpacing: -20,
            visibleCardCount: 0,
            currentHint: nil,
            showHintToast: false
        )
    }
}

#Preview("With Cards - Active") {
    ZStack {
        Color.Table.felt.ignoresSafeArea()
        PlayerHandView(
            hand: BlackjackHand(cards: [
                Card(suit: .clubs, rank: .eight),
                Card(suit: .hearts, rank: .nine)
            ], bet: 100),
            isActive: true,
            showCardCount: false,
            showAnimations: true,
            dealingSpeed: 1.0,
            handNumber: nil,
            cardWidth: 60,
            cardSpacing: -20,
            visibleCardCount: 2,
            currentHint: "Hit",
            showHintToast: true
        )
    }
}

#Preview("Soft Hand") {
    ZStack {
        Color.Table.felt.ignoresSafeArea()
        PlayerHandView(
            hand: BlackjackHand(cards: [
                Card(suit: .hearts, rank: .ace),
                Card(suit: .spades, rank: .seven)
            ], bet: 100),
            isActive: true,
            showCardCount: true,
            showAnimations: true,
            dealingSpeed: 1.0,
            handNumber: nil,
            cardWidth: 60,
            cardSpacing: -20,
            visibleCardCount: 2,
            currentHint: nil,
            showHintToast: false
        )
    }
}

#Preview("Split Hand - Inactive") {
    ZStack {
        Color.Table.felt.ignoresSafeArea()
        PlayerHandView(
            hand: BlackjackHand(cards: [
                Card(suit: .clubs, rank: .eight),
                Card(suit: .spades, rank: .jack)
            ], bet: 100),
            isActive: false,
            showCardCount: false,
            showAnimations: true,
            dealingSpeed: 1.0,
            handNumber: 2,
            cardWidth: 60,
            cardSpacing: -20,
            visibleCardCount: 2,
            currentHint: nil,
            showHintToast: false
        )
    }
}
