//
//  CompactHandView.swift
//  Baccarat
//
//  A compact view showing cards in a horizontal row.
//

import SwiftUI
import CasinoKit

/// A compact hand view showing cards in a row.
struct CompactHandView: View {
    let cards: [Card]
    let cardsFaceUp: [Bool]
    let isWinner: Bool
    /// Container width passed from parent for sizing
    let containerWidth: CGFloat
    let showAnimations: Bool
    let dealingSpeed: Double
    let revealStyle: RevealStyle
    let isWaitingForReveal: Bool
    let currentRevealIndex: Int
    let revealProgress: Double
    /// Whether this is the player hand (used to calculate reveal index)
    let isPlayerHand: Bool
    /// Whether this hand is currently displayed at the bottom of the screen (Home hand)
    let isBottom: Bool
    /// Whether the game is in dealing phase (vertical layout) vs betting phase (horizontal layout)
    let isDealing: Bool
    let onReveal: () -> Void
    let onUpdateProgress: (Double) -> Void
    
    // MARK: - Environment
    
    @Environment(\.horizontalSizeClass) private var horizontalSizeClass
    
    // MARK: - Constants
    
    /// Maximum number of cards in baccarat hand
    private let maxCards: Int = 3
    
    /// Placeholder spacing when no cards
    private let placeholderSpacing: CGFloat = Design.Spacing.small

    /// Spacing between cards
    private let cardSpacing: CGFloat = Design.Spacing.medium
    
    // MARK: - Computed Properties
    
    /// Whether we're on a large screen (iPad)
    private var isLargeScreen: Bool {
        horizontalSizeClass == .regular
    }
    
    /// WIN badge font size - larger on iPad
    private var winBadgeFontSize: CGFloat {
        isLargeScreen ? 14 : 10
    }
    
    /// Card width for dealt cards - sized to fit 3 cards with spacing
    private var cardWidth: CGFloat {
        // containerWidth = 3 * cardWidth + 2 * spacing
        // cardWidth = (containerWidth - 2 * spacing) / 3
        return max(50, (containerWidth - 2 * cardSpacing) / CGFloat(maxCards))
    }
    
    /// Card width for placeholders in horizontal betting view - uses original larger sizing
    private var bettingPlaceholderWidth: CGFloat {
        // Original formula: containerWidth / 2.1 (from overlap ratio of -0.45)
        containerWidth / 2.1
    }
    
    /// Card width to use for placeholders - larger in betting view, regular in dealing view
    private var placeholderWidth: CGFloat {
        isDealing ? cardWidth : bettingPlaceholderWidth
    }
    
    /// Card height based on aspect ratio
    private var cardHeight: CGFloat {
        let width = cards.isEmpty ? placeholderWidth : cardWidth
        return width * CasinoDesign.Size.cardAspectRatio
    }

    /// The effective spacing for the card stack
    private var effectiveSpacing: CGFloat {
        cards.isEmpty ? placeholderSpacing : cardSpacing
    }
    
    /// The actual width of the cards content (for winner border sizing)
    private var cardsContentWidth: CGFloat {
        if cards.isEmpty {
            // 2 placeholders with spacing
            return (2 * placeholderWidth) + placeholderSpacing
        } else {
            // N cards with (N-1) spacings
            let cardCount = CGFloat(cards.count)
            return (cardCount * cardWidth) + ((cardCount - 1) * cardSpacing)
        }
    }
    
    // MARK: - Body
    
    var body: some View {
        GeometryReader { geometry in
            let availableWidth = geometry.size.width
            
            if isLargeScreen || !isDealing {
                // iPad or betting phase: Simple centered layout - no scrolling needed
                cardsContentWithBorder
                    .frame(width: availableWidth, alignment: .center)
            } else {
                // iPhone dealing phase: Use ScrollView for 3rd card
                ScrollViewReader { proxy in
                    ScrollView(.horizontal, showsIndicators: false) {
                        cardsContentWithBorder
                            .frame(minWidth: availableWidth, alignment: .center)
                            .id("cards_container")
                    }
                    .scrollDisabled(cards.count < 3)
                    .scrollClipDisabled(true) // Prevent clipping during deal animations
                    .background(Color.clear)
                    .onChange(of: cards.count) { _, newCount in
                        // When 3rd card is dealt, wait for animation then scroll
                        if newCount == 3 {
                            let lastIndex = isBottom ? 4 : 5
                            DispatchQueue.main.asyncAfter(deadline: .now() + 0.8) {
                                withAnimation(.spring(duration: 0.5)) {
                                    proxy.scrollTo(lastIndex, anchor: .center)
                                }
                            }
                        }
                    }
                    .onChange(of: currentRevealIndex) { _, newIndex in
                        // Scroll to the active card during interaction
                        if newIndex >= 4 {
                            withAnimation(.spring(duration: 0.5)) {
                                proxy.scrollTo(newIndex, anchor: .center)
                            }
                        }
                    }
                }
            }
        }
        .frame(height: cardHeight + (isWinner ? Design.Spacing.small * 2 : 0))
        .frame(maxWidth: .infinity)
    }
    
    // MARK: - Private Views
    
    /// Cards content wrapped with the winner border sized to fit the actual cards
    private var cardsContentWithBorder: some View {
        cardsContent
            .padding(.horizontal, Design.Spacing.medium)
            .padding(.vertical, isWinner ? Design.Spacing.small : 0)
            .background(winnerBorder)
            .overlay(alignment: .bottom) {
                winBadge
            }
    }
    
    private var cardsContent: some View {
        HStack(spacing: effectiveSpacing) {
            if cards.isEmpty {
                // Placeholders - no overlap, just side by side
                ForEach(0..<2, id: \.self) { _ in
                    CardPlaceholderView(width: placeholderWidth)
                }
            } else {
                ForEach(cards.indices, id: \.self) { index in
                    let isFaceUp = index < cardsFaceUp.count ? cardsFaceUp[index] : false
                    
                    // Reveal Index logic:
                    // Generic Slot-Based: B1=0, T1=1, B2=2, T2=3, B3=4, T3=5
                    let revealIndex: Int = {
                        if index < 2 {
                            return isBottom ? index * 2 : index * 2 + 1
                        } else {
                            return isBottom ? 4 : 5
                        }
                    }()
                    
                    InteractiveCardView(
                        card: cards[index],
                        isFaceUp: isFaceUp,
                        cardWidth: cardWidth,
                        revealStyle: revealStyle,
                        isWaiting: isWaitingForReveal && currentRevealIndex == revealIndex,
                        progress: currentRevealIndex == revealIndex ? revealProgress : 0.0,
                        isBottomHand: isBottom,
                        onReveal: onReveal,
                        onUpdateProgress: onUpdateProgress
                    )
                    .id(revealIndex)
                    .zIndex(Double(index))
                    .transition(
                        showAnimations
                        ? .asymmetric(
                            insertion: .offset(x: Design.DealAnimation.offsetX, y: Design.DealAnimation.offsetY)
                                .combined(with: .opacity)
                                .combined(with: .scale(scale: Design.Scale.slightShrink)),
                            removal: .scale.combined(with: .opacity)
                        )
                        : .identity
                    )
                }
            }
        }
        .animation(
            showAnimations
            ? CasinoDesign.Animation.cardDeal(speed: dealingSpeed)
            : .none,
            value: cards.count
        )
    }
    
    private var winnerBorder: some View {
        RoundedRectangle(cornerRadius: Design.CornerRadius.small)
            .strokeBorder(
                isWinner ? Color.yellow : Color.clear,
                lineWidth: Design.LineWidth.standard
            )
    }
    
    @ViewBuilder
    private var winBadge: some View {
        if isWinner {
            Text("WIN")
                .font(.system(size: winBadgeFontSize, weight: .black))
                .foregroundStyle(.black)
                .padding(.horizontal, Design.Spacing.small)
                .padding(.vertical, Design.Spacing.xxSmall)
                .background(
                    Capsule()
                        .fill(Color.yellow)
                )
                .offset(y: Design.Spacing.small)
        }
    }
}

// MARK: - Previews

#Preview("Empty Hand - Betting") {
    ZStack {
        TableBackgroundView()
        CompactHandView(
            cards: [],
            cardsFaceUp: [],
            isWinner: false,
            containerWidth: 160,
            showAnimations: true,
            dealingSpeed: 1.0,
            revealStyle: .auto,
            isWaitingForReveal: false,
            currentRevealIndex: 0,
            revealProgress: 0,
            isPlayerHand: true,
            isBottom: true,
            isDealing: false,
            onReveal: {},
            onUpdateProgress: { _ in }
        )
    }
}

#Preview("Two Cards - Dealing") {
    ZStack {
        TableBackgroundView()
        CompactHandView(
            cards: [
                Card(suit: .spades, rank: .king),
                Card(suit: .hearts, rank: .eight)
            ],
            cardsFaceUp: [true, true],
            isWinner: false,
            containerWidth: 160,
            showAnimations: true,
            dealingSpeed: 1.0,
            revealStyle: .auto,
            isWaitingForReveal: false,
            currentRevealIndex: 0,
            revealProgress: 0,
            isPlayerHand: true,
            isBottom: true,
            isDealing: true,
            onReveal: {},
            onUpdateProgress: { _ in }
        )
    }
}

#Preview("Three Cards - Winner") {
    ZStack {
        TableBackgroundView()
        CompactHandView(
            cards: [
                Card(suit: .spades, rank: .four),
                Card(suit: .hearts, rank: .three),
                Card(suit: .clubs, rank: .two)
            ],
            cardsFaceUp: [true, true, true],
            isWinner: true,
            containerWidth: 160,
            showAnimations: true,
            dealingSpeed: 1.0,
            revealStyle: .auto,
            isWaitingForReveal: false,
            currentRevealIndex: 0,
            revealProgress: 0,
            isPlayerHand: true,
            isBottom: true,
            isDealing: true,
            onReveal: {},
            onUpdateProgress: { _ in }
        )
    }
}

#Preview("Cards Face Down") {
    ZStack {
        TableBackgroundView()
        CompactHandView(
            cards: [
                Card(suit: .diamonds, rank: .ace),
                Card(suit: .spades, rank: .seven)
            ],
            cardsFaceUp: [false, false],
            isWinner: false,
            containerWidth: 160,
            showAnimations: true,
            dealingSpeed: 1.0,
            revealStyle: .auto,
            isWaitingForReveal: false,
            currentRevealIndex: 0,
            revealProgress: 0,
            isPlayerHand: true,
            isBottom: true,
            isDealing: true,
            onReveal: {},
            onUpdateProgress: { _ in }
        )
    }
}

