//
//  BettingTableView.swift
//  Baccarat
//
//  The baccarat betting table layout with main bets and side bets.
//

import SwiftUI
import CasinoKit

/// The baccarat betting table layout with main bets and side bets.
struct BettingTableView: View {
    @Bindable var gameState: GameState
    let selectedChip: ChipDenomination
    
    // MARK: - Environment
    
    @Environment(\.verticalSizeClass) private var verticalSizeClass
    
    /// Whether we're in landscape mode (compact vertical)
    private var isLandscape: Bool {
        verticalSizeClass == .compact
    }
    
    // MARK: - Adaptive Sizes
    
    private let tableLimitsFontSize: CGFloat = Design.BaseFontSize.small
    
    /// Top bet row height - shorter in landscape
    private var topRowHeight: CGFloat {
        Design.Size.topBetRowHeight
    }
    
    /// Main bet row height - shorter in landscape
    private var mainRowHeight: CGFloat {
        Design.Size.mainBetRowHeight
    }
    
    // MARK: - Computed Properties
    
    private func betAmount(for type: BetType) -> Int {
        gameState.betAmount(for: type)
    }
    
    private func canAddBet(for type: BetType) -> Bool {
        gameState.canPlaceBet && 
        gameState.balance >= selectedChip.rawValue &&
        gameState.canAddToBet(type: type, amount: selectedChip.rawValue)
    }
    
    private func isAtMax(for type: BetType) -> Bool {
        betAmount(for: type) >= gameState.maxBet
    }
    
    private var isPlayerSelected: Bool {
        gameState.mainBet?.type == .player
    }
    
    private var isBankerSelected: Bool {
        gameState.mainBet?.type == .banker
    }
    
    private var tableLimitsText: String {
        String.localized(
            "tableLimitsFormat",
            gameState.minBet.formatted(),
            gameState.maxBet.formatted()
        )
    }
    
    // Use global debug flag from Design constants
    private var showDebugBorders: Bool { Design.showDebugBorders }
    
    // MARK: - Body
    
    var body: some View {
        VStack(spacing: Design.Spacing.small) {
            // Table limits label
            Text(tableLimitsText)
                .font(.system(size: tableLimitsFontSize, weight: .bold, design: .rounded))
                .foregroundStyle(.white.opacity(Design.Opacity.medium))
                .tracking(1)
                .lineLimit(1)
                .minimumScaleFactor(Design.MinScaleFactor.comfortable)
                .debugBorder(showDebugBorders, color: .gray, label: "Limits")
            
            // Main betting table
            VStack(spacing: 0) {
                // Top row: B PAIR | TIE | P PAIR
                TopBettingRow(
                    bankerPairAmount: betAmount(for: .bankerPair),
                    tieAmount: betAmount(for: .tie),
                    playerPairAmount: betAmount(for: .playerPair),
                    canBetBankerPair: canAddBet(for: .bankerPair),
                    canBetTie: canAddBet(for: .tie),
                    canBetPlayerPair: canAddBet(for: .playerPair),
                    isBankerPairAtMax: isAtMax(for: .bankerPair),
                    isTieAtMax: isAtMax(for: .tie),
                    isPlayerPairAtMax: isAtMax(for: .playerPair),
                    rowHeight: topRowHeight,
                    onBankerPair: { gameState.placeBet(type: .bankerPair, amount: selectedChip.rawValue) },
                    onTie: { gameState.placeBet(type: .tie, amount: selectedChip.rawValue) },
                    onPlayerPair: { gameState.placeBet(type: .playerPair, amount: selectedChip.rawValue) }
                )
                .debugBorder(showDebugBorders, color: .purple, label: "TopRow")
                
                // Divider
                Rectangle()
                    .fill(Color.Border.gold.opacity(Design.Opacity.medium))
                    .frame(height: Design.LineWidth.thin)
                
                // Middle row: BANKER | BONUS
                MainBetRow(
                    title: "BANKER",
                    payoutText: "0.95 : 1",
                    mainBetAmount: betAmount(for: .banker),
                    bonusBetAmount: betAmount(for: .dragonBonusBanker),
                    isSelected: isBankerSelected,
                    canBetMain: canAddBet(for: .banker),
                    canBetBonus: canAddBet(for: .dragonBonusBanker),
                    isMainAtMax: isAtMax(for: .banker),
                    isBonusAtMax: isAtMax(for: .dragonBonusBanker),
                    mainColor: Color.BettingZone.bankerDark,
                    rowHeight: mainRowHeight,
                    onMain: { gameState.placeBet(type: .banker, amount: selectedChip.rawValue) },
                    onBonus: { gameState.placeBet(type: .dragonBonusBanker, amount: selectedChip.rawValue) }
                )
                .debugBorder(showDebugBorders, color: .red, label: "BankerRow")
                
                // Divider
                Rectangle()
                    .fill(Color.Border.gold.opacity(Design.Opacity.medium))
                    .frame(height: Design.LineWidth.thin)
                
                // Bottom row: PLAYER | BONUS
                MainBetRow(
                    title: "PLAYER",
                    payoutText: "1 : 1",
                    mainBetAmount: betAmount(for: .player),
                    bonusBetAmount: betAmount(for: .dragonBonusPlayer),
                    isSelected: isPlayerSelected,
                    canBetMain: canAddBet(for: .player),
                    canBetBonus: canAddBet(for: .dragonBonusPlayer),
                    isMainAtMax: isAtMax(for: .player),
                    isBonusAtMax: isAtMax(for: .dragonBonusPlayer),
                    mainColor: Color.BettingZone.playerDark,
                    rowHeight: mainRowHeight,
                    onMain: { gameState.placeBet(type: .player, amount: selectedChip.rawValue) },
                    onBonus: { gameState.placeBet(type: .dragonBonusPlayer, amount: selectedChip.rawValue) }
                )
                .debugBorder(showDebugBorders, color: .blue, label: "PlayerRow")
            }
            .clipShape(RoundedRectangle(cornerRadius: Design.CornerRadius.large))
            .overlay(
                RoundedRectangle(cornerRadius: Design.CornerRadius.large)
                    .strokeBorder(
                        LinearGradient(
                            colors: [Color.CasinoTable.goldLight, Color.CasinoTable.goldDark],
                            startPoint: .top,
                            endPoint: .bottom
                        ),
                        lineWidth: Design.LineWidth.medium
                    )
            )
            .shadow(color: .black.opacity(Design.Opacity.light), radius: Design.Shadow.radiusLarge, y: Design.Shadow.offsetLarge)
        }
        .debugBorder(showDebugBorders, color: .orange, label: "BettingTable")
    }
}

// MARK: - Top Betting Row (B PAIR | TIE | P PAIR)

private struct TopBettingRow: View {
    let bankerPairAmount: Int
    let tieAmount: Int
    let playerPairAmount: Int
    let canBetBankerPair: Bool
    let canBetTie: Bool
    let canBetPlayerPair: Bool
    let isBankerPairAtMax: Bool
    let isTieAtMax: Bool
    let isPlayerPairAtMax: Bool
    let rowHeight: CGFloat
    let onBankerPair: () -> Void
    let onTie: () -> Void
    let onPlayerPair: () -> Void
    
    var body: some View {
        HStack(spacing: 0) {
            // B PAIR
            PairBetZone(
                title: "B PAIR",
                betAmount: bankerPairAmount,
                isEnabled: canBetBankerPair,
                isAtMax: isBankerPairAtMax,
                color: Color.BettingZone.bankerDark.opacity(Design.Opacity.accent),
                action: onBankerPair
            )
            
            // Vertical divider
            Rectangle()
                .fill(Color.Border.gold.opacity(Design.Opacity.medium))
                .frame(width: Design.LineWidth.thin)
            
            // TIE
            TieBetZone(
                betAmount: tieAmount,
                isEnabled: canBetTie,
                isAtMax: isTieAtMax,
                action: onTie
            )
            
            // Vertical divider
            Rectangle()
                .fill(Color.Border.gold.opacity(Design.Opacity.medium))
                .frame(width: Design.LineWidth.thin)
            
            // P PAIR
            PairBetZone(
                title: "P PAIR",
                betAmount: playerPairAmount,
                isEnabled: canBetPlayerPair,
                isAtMax: isPlayerPairAtMax,
                color: Color.BettingZone.playerDark.opacity(Design.Opacity.accent),
                action: onPlayerPair
            )
        }
        .frame(height: rowHeight)
    }
}

// MARK: - Pair Bet Zone

private struct PairBetZone: View {
    let title: String
    let betAmount: Int
    let isEnabled: Bool
    let isAtMax: Bool
    let color: Color
    let action: () -> Void
    
    var body: some View {
        Button {
            if isEnabled { action() }
        } label: {
            ZStack {
                // Background
                Rectangle()
                    .fill(color)
                
                // Content
                VStack(spacing: Design.Spacing.xxSmall) {
                    Text(title)
                        .font(.system(size: Design.BaseFontSize.body, weight: .heavy, design: .rounded))
                        .foregroundStyle(.yellow)
                    
                    Text("11 : 1")
                        .font(.system(size: Design.BaseFontSize.small, weight: .medium, design: .rounded))
                        .foregroundStyle(.white.opacity(Design.Opacity.strong))
                }
                
                // Chip indicator - center right with padding
                if betAmount > 0 {
                    HStack {
                        Spacer()
                        ChipBadge(amount: betAmount, isMax: isAtMax)
                            .padding(.trailing, Design.Spacing.xSmall + Design.Spacing.xxSmall)
                    }
                }
            }
        }
        .buttonStyle(.plain)
        .accessibilityElement(children: .ignore)
        .accessibilityLabel("\(title) bet, pays 11 to 1" + (betAmount > 0 ? ", current bet $\(betAmount)" : ""))
        .accessibilityAddTraits(.isButton)
    }
}

// MARK: - Tie Bet Zone

private struct TieBetZone: View {
    let betAmount: Int
    let isEnabled: Bool
    let isAtMax: Bool
    let action: () -> Void
    
    var body: some View {
        Button {
            if isEnabled { action() }
        } label: {
            ZStack {
                // Background
                Rectangle()
                    .fill(isAtMax ? Color.BettingZone.tieMax : Color.BettingZone.tie)
                
                // Content
                VStack(spacing: Design.Spacing.xxSmall) {
                    Text("TIE")
                        .font(.system(size: Design.BaseFontSize.medium, weight: .black, design: .rounded))
                        .tracking(1)
                    
                    Text("8 : 1")
                        .font(.system(size: Design.BaseFontSize.small, weight: .medium, design: .rounded))
                        .opacity(Design.Opacity.strong)
                }
                .foregroundStyle(.white)
                
                // Chip indicator - center right with padding
                if betAmount > 0 {
                    HStack {
                        Spacer()
                        ChipBadge(amount: betAmount, isMax: isAtMax)
                            .padding(.trailing, Design.Spacing.xSmall + Design.Spacing.xxSmall)
                    }
                }
            }
        }
        .buttonStyle(.plain)
        .accessibilityElement(children: .ignore)
        .accessibilityLabel("Tie bet, pays 8 to 1" + (betAmount > 0 ? ", current bet $\(betAmount)" : ""))
        .accessibilityAddTraits(.isButton)
    }
}

// MARK: - Main Bet Row (BANKER/PLAYER with BONUS)

private struct MainBetRow: View {
    let title: String
    let payoutText: String
    let mainBetAmount: Int
    let bonusBetAmount: Int
    let isSelected: Bool
    let canBetMain: Bool
    let canBetBonus: Bool
    let isMainAtMax: Bool
    let isBonusAtMax: Bool
    let mainColor: Color
    let rowHeight: CGFloat
    let onMain: () -> Void
    let onBonus: () -> Void
    
    var body: some View {
        HStack(spacing: 0) {
            // Main bet zone (BANKER or PLAYER)
            MainBetZone(
                title: title,
                payoutText: payoutText,
                betAmount: mainBetAmount,
                isSelected: isSelected,
                isEnabled: canBetMain,
                isAtMax: isMainAtMax,
                color: mainColor,
                action: onMain
            )
            
            // Vertical divider
            Rectangle()
                .fill(Color.Border.gold.opacity(Design.Opacity.medium))
                .frame(width: Design.LineWidth.thin)
            
            // Dragon Bonus zone
            DragonBonusZone(
                betAmount: bonusBetAmount,
                isEnabled: canBetBonus,
                isAtMax: isBonusAtMax,
                action: onBonus
            )
            .frame(width: Design.Size.bonusZoneWidth)
        }
        .frame(height: rowHeight)
    }
}

// MARK: - Main Bet Zone (BANKER or PLAYER)

private struct MainBetZone: View {
    let title: String
    let payoutText: String
    let betAmount: Int
    let isSelected: Bool
    let isEnabled: Bool
    let isAtMax: Bool
    let color: Color
    let action: () -> Void
    
    var body: some View {
        Button {
            if isEnabled { action() }
        } label: {
            ZStack {
                // Background
                Rectangle()
                    .fill(color)
                
                // Selection highlight
                if isSelected {
                    Rectangle()
                        .fill(Color.yellow.opacity(Design.Opacity.selection))
                    
                    Rectangle()
                        .strokeBorder(Color.yellow, lineWidth: Design.LineWidth.thick)
                }
                
                // Content - always centered
                VStack(spacing: Design.Spacing.xxSmall + 1) {
                    Text(title)
                        .font(.system(size: Design.BaseFontSize.xLarge, weight: .black, design: .rounded))
                        .tracking(2)
                    
                    Text(payoutText)
                        .font(.system(size: Design.BaseFontSize.callout - 2, weight: .semibold, design: .rounded))
                        .opacity(Design.Opacity.strong)
                }
                .foregroundStyle(.white)
                
                // Chip indicator - overlaid on right, doesn't affect centering
                if betAmount > 0 {
                    HStack {
                        Spacer()
                        ChipOnTableView(amount: betAmount, showMax: isAtMax)
                            .padding(.trailing, Design.Spacing.small)
                    }
                }
            }
        }
        .buttonStyle(.plain)
        .accessibilityElement(children: .ignore)
        .accessibilityLabel("\(title) bet, pays \(payoutText)" + (isSelected ? ", selected" : "") + (betAmount > 0 ? ", current bet $\(betAmount)" : ""))
        .accessibilityAddTraits(.isButton)
    }
}

// MARK: - Dragon Bonus Zone

private struct DragonBonusZone: View {
    let betAmount: Int
    let isEnabled: Bool
    let isAtMax: Bool
    let action: () -> Void
    
    var body: some View {
        Button {
            if isEnabled { action() }
        } label: {
            ZStack {
                // Background - darker purple/blue tint
                Rectangle()
                    .fill(
                        LinearGradient(
                            colors: [
                                Color.BettingZone.dragonBonusLight,
                                Color.BettingZone.dragonBonusDark
                            ],
                            startPoint: .top,
                            endPoint: .bottom
                        )
                    )
                
                // Content
                VStack(spacing: Design.Spacing.xSmall) {
                    // Diamond shape
                    DiamondShape()
                        .fill(
                            LinearGradient(
                                colors: [Color.purple.opacity(Design.Opacity.heavy), Color.purple.opacity(Design.Opacity.medium)],
                                startPoint: .top,
                                endPoint: .bottom
                            )
                        )
                        .frame(width: Design.Size.diamondIcon, height: Design.Size.diamondIcon)
                        .overlay(
                            DiamondShape()
                                .strokeBorder(Color.white.opacity(Design.Opacity.overlay), lineWidth: Design.LineWidth.thin)
                        )
                    
                    Text("BONUS")
                        .font(.system(size: Design.BaseFontSize.xSmall, weight: .bold, design: .rounded))
                        .foregroundStyle(.white.opacity(Design.Opacity.almostFull))
                }
                
                // Chip indicator - center right with padding (same as top row)
                if betAmount > 0 {
                    HStack {
                        Spacer()
                        ChipBadge(amount: betAmount, isMax: isAtMax)
                            .padding(.trailing, Design.Spacing.xSmall + Design.Spacing.xxSmall)
                    }
                }
            }
        }
        .buttonStyle(.plain)
        .accessibilityElement(children: .ignore)
        .accessibilityLabel("Dragon Bonus, pays up to 30 to 1" + (betAmount > 0 ? ", current bet $\(betAmount)" : ""))
        .accessibilityAddTraits(.isButton)
    }
}

// MARK: - Diamond Shape

private struct DiamondShape: InsettableShape {
    var insetAmount: CGFloat = 0
    
    func path(in rect: CGRect) -> Path {
        var path = Path()
        let insetRect = rect.insetBy(dx: insetAmount, dy: insetAmount)
        
        path.move(to: CGPoint(x: insetRect.midX, y: insetRect.minY))
        path.addLine(to: CGPoint(x: insetRect.maxX, y: insetRect.midY))
        path.addLine(to: CGPoint(x: insetRect.midX, y: insetRect.maxY))
        path.addLine(to: CGPoint(x: insetRect.minX, y: insetRect.midY))
        path.closeSubpath()
        
        return path
    }
    
    func inset(by amount: CGFloat) -> some InsettableShape {
        var shape = self
        shape.insetAmount += amount
        return shape
    }
}

// MARK: - Chip Badge (indicator for side bets)

private struct ChipBadge: View {
    let amount: Int
    let isMax: Bool
    
    var body: some View {
        ZStack {
            // Outer ring
            Circle()
                .fill(isMax ? Color.gray : Color.yellow)
                .frame(width: CasinoDesign.Size.chipBadge, height: CasinoDesign.Size.chipBadge)
            
            // Inner decoration
            Circle()
                .strokeBorder(Color.white.opacity(Design.Opacity.almostFull), lineWidth: Design.LineWidth.standard)
                .frame(width: CasinoDesign.Size.chipBadgeInner, height: CasinoDesign.Size.chipBadgeInner)
            
            // Text
            if isMax {
                Text("MAX")
                    .font(.system(size: Design.BaseFontSize.xSmall, weight: .black))
                    .foregroundStyle(.white)
            } else {
                Text(formatCompact(amount))
                    .font(.system(size: Design.BaseFontSize.body, weight: .bold, design: .rounded))
                    .foregroundStyle(.black)
            }
        }
        .shadow(color: .black.opacity(Design.Opacity.light), radius: Design.Shadow.radiusSmall, y: Design.Shadow.offsetSmall)
    }
    
    private func formatCompact(_ value: Int) -> String {
        if value >= 1000 {
            return "\(value / 1000)K"
        }
        return "\(value)"
    }
}

// MARK: - Previews

#Preview("Betting Table") {
    ZStack {
        TableBackgroundView()
        
        BettingTableView(
            gameState: GameState(settings: GameSettings()),
            selectedChip: .hundred
        )
        .padding()
    }
}

#Preview("With Bets") {
    ZStack {
        TableBackgroundView()
        
        BettingTableView(
            gameState: {
                let state = GameState(settings: GameSettings())
                state.placeBet(type: .player, amount: 100)
                state.placeBet(type: .tie, amount: 25)
                return state
            }(),
            selectedChip: .hundred
        )
        .padding()
    }
}
