//
//  BlackjackTableView.swift
//  Blackjack
//
//  The main table layout showing dealer and player hands.
//

import SwiftUI
import CasinoKit

struct BlackjackTableView: View {
    @Bindable var state: GameState
    let selectedChip: ChipDenomination
    
    /// Full screen size passed from parent (stable - measured from TableBackgroundView)
    let fullScreenSize: CGSize
    
    // MARK: - Environment
    
    @Environment(\.verticalSizeClass) private var verticalSizeClass
    
    
    // MARK: - Computed from stable screen size
    
    private var screenWidth: CGFloat { fullScreenSize.width }
    private var screenHeight: CGFloat { fullScreenSize.height }
    
    /// Whether to show Hi-Lo card count values on cards.
    var showCardCount: Bool { state.settings.showCardCount }
    
    // MARK: - Scaled Metrics
    
    @ScaledMetric(relativeTo: .headline) private var labelFontSize: CGFloat = Design.BaseFontSize.medium
    @ScaledMetric(relativeTo: .title) private var valueFontSize: CGFloat = Design.BaseFontSize.xLarge
    
    // MARK: - Dynamic Card Sizing
    
    /// Whether we're in landscape mode
    /// - iPhones: use verticalSizeClass == .compact
    /// - iPads: use screen dimensions (since iPads always report .regular)
    private var isLandscape: Bool {
        if DeviceInfo.isPad {
            return screenWidth > screenHeight
        }
        return verticalSizeClass == .compact
    }
    
    /// Card width based on full screen height (stable - doesn't change with content)
    private var cardWidth: CGFloat {
        let maxDimension = screenHeight        
        let percentage: CGFloat = 0.18  // ~10% of screen
        return maxDimension * percentage
    }
    
    /// Card overlap scales proportionally with card width
    private var cardSpacing: CGFloat {
        // Overlap ratio: roughly -55% of card width
        cardWidth * -0.55
    }
    
    // Use global debug flag from Design constants
    private var showDebugBorders: Bool { Design.showDebugBorders }
    
    // MARK: - Hint Toast Helper
    
    /// Shows the hint toast with auto-dismiss timer.
    private func showHintToastWithTimer(state: GameState) {
        // Generate new ID to invalidate any pending dismiss tasks
        let currentID = UUID()
        state.hintDisplayID = currentID
        
        withAnimation(.spring(duration: Design.Animation.springDuration)) {
            state.showHintToast = true
        }
        // Auto-dismiss after delay, but only if this is still the active hint session
        Task { @MainActor in
            try? await Task.sleep(for: Design.Toast.duration)
            // Only dismiss if no newer hint has arrived
            if state.hintDisplayID == currentID {
                withAnimation(.spring(duration: Design.Animation.springDuration)) {
                    state.showHintToast = false
                }
            }
        }
    }
    
    var body: some View {
        VStack(spacing: 0) {
            // Dealer area
            DealerHandView(
                hand: state.dealerHand,
                showHoleCard: state.shouldShowDealerHoleCard,
                showCardCount: showCardCount,
                showAnimations: state.settings.showAnimations,
                dealingSpeed: state.settings.dealingSpeed,
                cardWidth: cardWidth,
                cardSpacing: cardSpacing
            )
            .debugBorder(showDebugBorders, color: .red, label: "Dealer")
            
            // Top spacer
            Spacer(minLength: Design.Spacing.small)
                .debugBorder(showDebugBorders, color: .yellow, label: "TopSpacer")
            
            // Card count view centered between dealer and player
            if showCardCount {
                CardCountView(
                    runningCount: state.engine.runningCount,
                    trueCount: state.engine.trueCount
                )
                .debugBorder(showDebugBorders, color: .mint, label: "CardCount")
            }
            
            // Bottom spacer
            Spacer(minLength: Design.Spacing.small)
                .debugBorder(showDebugBorders, color: .yellow, label: "BottomSpacer")
            
            // Player hands area - only show when there are cards dealt
            if state.playerHands.first?.cards.isEmpty == false {
                ZStack {
                PlayerHandsView(
                    hands: state.playerHands,
                    activeHandIndex: state.activeHandIndex,
                    isPlayerTurn: state.isPlayerTurn,
                    showCardCount: showCardCount,
                    showAnimations: state.settings.showAnimations,
                    dealingSpeed: state.settings.dealingSpeed,
                    cardWidth: cardWidth,
                    cardSpacing: cardSpacing,
                    currentHint: state.currentHint,
                    showHintToast: state.showHintToast
                )
                    
                    // Side bet toasts (positioned on left/right sides to not cover cards)
                    if state.settings.sideBetsEnabled && state.showSideBetToasts {
                        HStack {
                            // PP on left
                            if state.perfectPairsBet > 0, let ppResult = state.perfectPairsResult {
                                SideBetToastView(
                                    title: "PP",
                                    result: ppResult.displayName,
                                    isWin: ppResult.isWin,
                                    amount: ppResult.isWin ? state.perfectPairsBet * ppResult.payout : -state.perfectPairsBet,
                                    showOnLeft: true
                                )
                            }
                            
                            Spacer()
                            
                            // 21+3 on right
                            if state.twentyOnePlusThreeBet > 0, let topResult = state.twentyOnePlusThreeResult {
                                SideBetToastView(
                                    title: "21+3",
                                    result: topResult.displayName,
                                    isWin: topResult.isWin,
                                    amount: topResult.isWin ? state.twentyOnePlusThreeBet * topResult.payout : -state.twentyOnePlusThreeBet,
                                    showOnLeft: false
                                )
                            }
                        }
                        .padding(.horizontal, Design.Spacing.small)
                    }
                }
                .onChange(of: state.currentHint) { oldHint, newHint in
                    // Show toast when a new hint appears
                    if let hint = newHint, hint != oldHint {
                        showHintToastWithTimer(state: state)
                    } else if newHint == nil {
                        // Hide immediately when no hint
                        state.hintDisplayID = UUID() // Invalidate any pending dismiss tasks
                        withAnimation(.spring(duration: Design.Animation.springDuration)) {
                            state.showHintToast = false
                        }
                    }
                }
                .onChange(of: state.playerHands.count) { _, _ in
                    // Show hint when hands are added (split occurred)
                    if state.currentHint != nil {
                        showHintToastWithTimer(state: state)
                    }
                }
                .onChange(of: state.activeHandIndex) { _, _ in
                    // Show hint when active hand changes (moved to next hand after split)
                    if state.currentHint != nil {
                        showHintToastWithTimer(state: state)
                    }
                }
                .onChange(of: state.activeHand?.cards.count) { _, newCount in
                    // Show hint when a card is added to the active hand (after hit)
                    guard let count = newCount, count > 2, state.currentHint != nil else { return }
                    // Small delay to let card animation settle before showing hint
                    Task { @MainActor in
                        try? await Task.sleep(for: .milliseconds(250))
                        if state.currentHint != nil {
                            showHintToastWithTimer(state: state)
                        }
                    }
                }
                .padding(.bottom, 5)
                .transition(.opacity)
                .debugBorder(showDebugBorders, color: .green, label: "Player")
            }
            
            // Betting zone (when betting)
            if state.currentPhase == .betting {
                Spacer()
                    .debugBorder(showDebugBorders, color: .yellow, label: "Spacer2")
                
                BettingZoneView(
                    state: state,
                    selectedChip: selectedChip
                )
                .transition(.scale.combined(with: .opacity))
                .debugBorder(showDebugBorders, color: .blue, label: "BetZone")
                
                // Betting hint based on count (only when card counting enabled)
                if let hint = state.bettingHint {
                    BettingHintView(hint: hint, trueCount: state.engine.trueCount)
                        .transition(.opacity)
                        .padding(.vertical, 10)
                        .debugBorder(showDebugBorders, color: .purple, label: "BetHint")
                }
            }
        }
        .padding(.horizontal, Design.Spacing.large)
        .debugBorder(showDebugBorders, color: .white, label: "TableView")
        .animation(.spring(duration: Design.Animation.springDuration), value: state.currentPhase)
    }
}

// MARK: - Previews

#Preview {
    ZStack {
        Color.Table.felt.ignoresSafeArea()
        Text("Use GameTableView for full preview")
            .foregroundStyle(.white)
    }
}
