//
//  PlayerHandView.swift
//  Blackjack
//
//  Displays player hands in a horizontally scrollable container.
//

import SwiftUI
import CasinoKit

// MARK: - Player Hands Container

/// Container for multiple player hands with horizontal scrolling.
struct PlayerHandsView: View {
    let hands: [BlackjackHand]
    let activeHandIndex: Int
    let isPlayerTurn: Bool
    let showCardCount: Bool
    let showAnimations: Bool
    let dealingSpeed: Double
    let cardWidth: CGFloat
    let cardSpacing: CGFloat
    
    /// Current hint to display (shown on active hand only).
    let currentHint: String?
    
    /// Whether the hint toast should be visible.
    let showHintToast: Bool
    
    /// Total card count across all hands - used to trigger scroll when hitting
    private var totalCardCount: Int {
        hands.reduce(0) { $0 + $1.cards.count }
    }
    
    var body: some View {
        ScrollViewReader { proxy in
            ScrollView(.horizontal, showsIndicators: false) {
                HStack(spacing: Design.Spacing.large) {
                    // Display hands in reverse order (right to left play order)
                    // Visual order: Hand 3, Hand 2, Hand 1 (left to right)
                    // Play order: Hand 1 played first (rightmost), then Hand 2, etc.
                    ForEach(Array(hands.enumerated()).reversed(), id: \.element.id) { index, hand in
                        let isActiveHand = index == activeHandIndex && isPlayerTurn
                        PlayerHandView(
                            hand: hand,
                            isActive: isActiveHand,
                            showCardCount: showCardCount,
                            showAnimations: showAnimations,
                            dealingSpeed: dealingSpeed,
                            // Hand numbers: rightmost (index 0) is Hand 1, played first
                            handNumber: hands.count > 1 ? index + 1 : nil,
                            cardWidth: cardWidth,
                            cardSpacing: cardSpacing,
                            // Only show hint on the active hand
                            currentHint: isActiveHand ? currentHint : nil,
                            showHintToast: isActiveHand && showHintToast
                        )
                        .id(hand.id)
                        .transition(.scale.combined(with: .opacity))
                    }
                }
                .animation(.spring(duration: Design.Animation.springDuration), value: hands.count)
                .padding(.horizontal, Design.Spacing.xxLarge)  // More padding for scrolling
            }
            .scrollClipDisabled()
            .scrollBounceBehavior(.always)  // Always allow bouncing for better scroll feel
            .defaultScrollAnchor(.center)   // Center the content by default
            .onChange(of: activeHandIndex) { _, newIndex in
                scrollToActiveHand(proxy: proxy)
            }
            .onChange(of: totalCardCount) { _, _ in
                // Scroll to active hand when cards are added (hit)
                scrollToActiveHand(proxy: proxy)
            }
            .onChange(of: hands.count) { _, _ in
                // Scroll to active hand when split occurs
                scrollToActiveHand(proxy: proxy)
            }
            .onAppear {
                scrollToActiveHand(proxy: proxy)
            }
        }
        .frame(maxWidth: .infinity)
    }
    
    private func scrollToActiveHand(proxy: ScrollViewProxy) {
        guard activeHandIndex < hands.count else { return }
        let activeHandId = hands[activeHandIndex].id
        withAnimation(.easeInOut(duration: Design.Animation.quick)) {
            proxy.scrollTo(activeHandId, anchor: .center)
        }
    }
}

// MARK: - Single Player Hand

/// 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
    
    /// Current hint to display on this hand.
    let currentHint: String?
    
    /// Whether the hint toast should be visible.
    let showHintToast: Bool
    
    /// Scaled animation duration based on dealing speed.
    private var animationDuration: Double {
        Design.Animation.springDuration * dealingSpeed
    }
    
    @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
    
    var body: some View {
        VStack(spacing: Design.Spacing.small) {
            // Cards with container
            HStack(spacing: hand.cards.isEmpty ? Design.Spacing.small : cardSpacing) {
                if hand.cards.isEmpty {
                    CardPlaceholderView(width: cardWidth)
                    CardPlaceholderView(width: cardWidth)
                } else {
                    ForEach(hand.cards.indices, id: \.self) { index in
                        CardView(
                            card: hand.cards[index],
                            isFaceUp: true,
                            cardWidth: cardWidth
                        )
                        .overlay(alignment: .bottomLeading) {
                            if showCardCount {
                                HiLoCountBadge(card: hand.cards[index])
                            }
                        }
                        .zIndex(Double(index))
                        .transition(
                            showAnimations
                            ? .asymmetric(
                                insertion: .offset(x: Design.DealAnimation.playerOffsetX, y: Design.DealAnimation.playerOffsetY)
                                    .combined(with: .opacity)
                                    .combined(with: .scale(scale: Design.Scale.slightShrink)),
                                removal: .scale.combined(with: .opacity)
                            )
                            : .identity
                        )
                    }
                }
            }
            .animation(
                showAnimations
                ? .spring(duration: animationDuration, bounce: Design.Animation.springBounce)
                : .none,
                value: hand.cards.count
            )
            .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)
            
            // Hand info
            HStack(spacing: Design.Spacing.small) {
                if let number = handNumber {
                    Text(String(localized: "Hand \(number)"))
                        .font(.system(size: handNumberSize, weight: .medium))
                        .foregroundStyle(.white.opacity(Design.Opacity.medium))
                }
                
                if !hand.cards.isEmpty {
                    Text(hand.valueDisplay)
                        .font(.system(size: labelFontSize, weight: .bold, design: .rounded))
                        .foregroundStyle(valueColor)
                }
                
                if hand.isDoubledDown {
                    Image(systemName: "xmark.circle.fill")
                        .font(.system(size: iconSize))
                        .foregroundStyle(.purple)
                }
            }
            
            // Bet amount
            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)
                }
            }
        }
        .accessibilityElement(children: .ignore)
        .accessibilityLabel(playerAccessibilityLabel)
    }
    
    // MARK: - Computed Properties
    
    private var valueColor: Color {
        if hand.isBlackjack { return .yellow }
        if hand.isBusted { return .red }
        if hand.value == 21 { return .green }
        return .white
    }
    
    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("Single Hand - Empty") {
    ZStack {
        Color.Table.felt.ignoresSafeArea()
        PlayerHandsView(
            hands: [BlackjackHand()],
            activeHandIndex: 0,
            isPlayerTurn: true,
            showCardCount: false,
            showAnimations: true,
            dealingSpeed: 1.0,
            cardWidth: 60,
            cardSpacing: -20,
            currentHint: nil,
            showHintToast: false
        )
    }
}

#Preview("Single Hand - Cards") {
    ZStack {
        Color.Table.felt.ignoresSafeArea()
        PlayerHandsView(
            hands: [BlackjackHand(cards: [
                Card(suit: .clubs, rank: .eight),
                Card(suit: .hearts, rank: .nine)
            ], bet: 100)],
            activeHandIndex: 0,
            isPlayerTurn: true,
            showCardCount: false,
            showAnimations: true,
            dealingSpeed: 1.0,
            cardWidth: 60,
            cardSpacing: -20,
            currentHint: "Hit",
            showHintToast: true
        )
    }
}

#Preview("Split Hands") {
    ZStack {
        Color.Table.felt.ignoresSafeArea()
        PlayerHandsView(
            hands: [
                BlackjackHand(cards: [
                    Card(suit: .clubs, rank: .eight),
                    Card(suit: .spades, rank: .jack)
                ], bet: 100),
                BlackjackHand(cards: [
                    Card(suit: .hearts, rank: .eight),
                    Card(suit: .diamonds, rank: .five)
                ], bet: 100),
                BlackjackHand(cards: [
                    Card(suit: .hearts, rank: .eight),
                    Card(suit: .diamonds, rank: .five)
                ], bet: 100),
                BlackjackHand(cards: [
                    Card(suit: .hearts, rank: .eight),
                    Card(suit: .diamonds, rank: .five)
                ], bet: 100)
            ],
            activeHandIndex: 1,
            isPlayerTurn: true,
            showCardCount: true,
            showAnimations: true,
            dealingSpeed: 1.0,
            cardWidth: 60,
            cardSpacing: -20,
            currentHint: "Stand",
            showHintToast: true
        )
    }
}

