//
//  BettingActionsView.swift
//  CasinoKit
//
//  Reusable Clear/Deal button pair for casino games betting phase.
//

import SwiftUI

/// A reusable view that displays Clear and Deal buttons for casino game betting phases.
///
/// This view follows the "always visible, disabled when unavailable" pattern for better UX:
/// - Buttons are always shown to maintain layout stability
/// - Clear is disabled when no bet is placed
/// - Deal is disabled when the bet doesn't meet requirements
/// - Optional minimum bet hint displays when bet is below minimum
public struct BettingActionsView: View {
    
    // MARK: - Properties
    
    /// Whether the player has any bet placed.
    public let hasBet: Bool
    
    /// Whether the deal action is currently available.
    public let canDeal: Bool
    
    /// Amount needed to reach minimum bet (shown as hint when > 0).
    public let amountNeededForMinimum: Int?
    
    /// Action when Clear is tapped.
    public let onClear: () -> Void
    
    /// Action when Deal is tapped.
    public let onDeal: () -> Void
    
    // MARK: - Environment
    
    @Environment(\.dynamicTypeSize) private var dynamicTypeSize
    
    /// Whether the current text size is an accessibility size (very large).
    private var isAccessibilitySize: Bool {
        dynamicTypeSize.isAccessibilitySize
    }
    
    // MARK: - Layout Constants
    
    private let buttonFontSize: CGFloat = CasinoDesign.BaseFontSize.xLarge
    private let iconSize: CGFloat = CasinoDesign.BaseFontSize.xxLarge + CasinoDesign.Spacing.xSmall
    private let hintFontSize: CGFloat = CasinoDesign.BaseFontSize.small
    
    // MARK: - Initialization
    
    /// Creates a betting actions view.
    /// - Parameters:
    ///   - hasBet: Whether there is any bet placed.
    ///   - canDeal: Whether deal is currently available.
    ///   - amountNeededForMinimum: Optional amount needed to reach minimum (shown as hint).
    ///   - onClear: Action when Clear is tapped.
    ///   - onDeal: Action when Deal is tapped.
    public init(
        hasBet: Bool,
        canDeal: Bool,
        amountNeededForMinimum: Int? = nil,
        onClear: @escaping () -> Void,
        onDeal: @escaping () -> Void
    ) {
        self.hasBet = hasBet
        self.canDeal = canDeal
        self.amountNeededForMinimum = amountNeededForMinimum
        self.onClear = onClear
        self.onDeal = onDeal
    }
    
    // MARK: - Body
    
    public var body: some View {
        VStack(spacing: CasinoDesign.Spacing.small) {
            // Show hint if bet is below minimum
            if let amount = amountNeededForMinimum, amount > 0 {
                Text(String(localized: "Add $\(amount) more to meet minimum", bundle: .module))
                    .font(.system(size: hintFontSize, weight: .medium))
                    .foregroundStyle(.orange)
                    .transition(.opacity.combined(with: .scale(scale: 0.8)))
            }
            
            HStack(spacing: CasinoDesign.Spacing.medium) {
                clearButton
                dealButton
            }
        }
        .animation(.easeInOut(duration: CasinoDesign.Animation.standard), value: amountNeededForMinimum)
    }
    
    // MARK: - Private Views
    
    @ViewBuilder
    private var clearButton: some View {
        let isEnabled = hasBet
        
        if isAccessibilitySize {
            Button("Clear", systemImage: "xmark.circle", action: onClear)
                .labelStyle(.iconOnly)
                .font(.system(size: iconSize, weight: .semibold))
                .foregroundStyle(.white)
                .padding(CasinoDesign.Spacing.medium + CasinoDesign.Spacing.xxSmall)
                .background(
                    Circle()
                        .fill(Color.CasinoButton.destructive)
                )
                .opacity(isEnabled ? 1.0 : CasinoDesign.Opacity.disabled)
                .disabled(!isEnabled)
                .accessibilityLabel(String(localized: "Clear bet", bundle: .module))
        } else {
            Button("Clear", systemImage: "xmark.circle", action: onClear)
                .labelStyle(.titleAndIcon)
                .font(.system(size: buttonFontSize, weight: .semibold))
                .foregroundStyle(.white)
                .padding(.horizontal, CasinoDesign.Spacing.xxLarge)
                .padding(.vertical, CasinoDesign.Spacing.medium + CasinoDesign.Spacing.xxSmall)
                .background(
                    Capsule()
                        .fill(Color.CasinoButton.destructive)
                )
                .opacity(isEnabled ? 1.0 : CasinoDesign.Opacity.disabled)
                .disabled(!isEnabled)
                .accessibilityLabel(String(localized: "Clear bet", bundle: .module))
        }
    }
    
    @ViewBuilder
    private var dealButton: some View {
        let buttonBackground = LinearGradient(
            colors: [Color.CasinoButton.goldLight, Color.CasinoButton.goldDark],
            startPoint: .top,
            endPoint: .bottom
        )
        
        if isAccessibilitySize {
            Button("Deal", systemImage: "play.fill", action: onDeal)
                .labelStyle(.iconOnly)
                .font(.system(size: iconSize, weight: .bold))
                .foregroundStyle(.black)
                .padding(CasinoDesign.Spacing.medium + CasinoDesign.Spacing.xxSmall)
                .background(
                    Circle()
                        .fill(buttonBackground)
                )
                .shadow(color: .yellow.opacity(CasinoDesign.Opacity.light), radius: CasinoDesign.Shadow.radiusMedium)
                .opacity(canDeal ? 1.0 : CasinoDesign.Opacity.disabled)
                .disabled(!canDeal)
                .accessibilityLabel(String(localized: "Deal cards", bundle: .module))
        } else {
            Button("Deal", systemImage: "play.fill", action: onDeal)
                .labelStyle(.titleAndIcon)
                .font(.system(size: buttonFontSize, weight: .bold))
                .foregroundStyle(.black)
                .padding(.horizontal, CasinoDesign.Spacing.xxLarge)
                .padding(.vertical, CasinoDesign.Spacing.medium + CasinoDesign.Spacing.xxSmall)
                .background(
                    Capsule()
                        .fill(buttonBackground)
                )
                .shadow(color: .yellow.opacity(CasinoDesign.Opacity.light), radius: CasinoDesign.Shadow.radiusMedium)
                .opacity(canDeal ? 1.0 : CasinoDesign.Opacity.disabled)
                .disabled(!canDeal)
                .accessibilityLabel(String(localized: "Deal cards", bundle: .module))
        }
    }
}

// MARK: - Previews

#Preview("No Bet Placed") {
    ZStack {
        Color.CasinoTable.felt.ignoresSafeArea()
        BettingActionsView(
            hasBet: false,
            canDeal: false,
            onClear: {},
            onDeal: {}
        )
    }
}

#Preview("Bet Below Minimum") {
    ZStack {
        Color.CasinoTable.felt.ignoresSafeArea()
        BettingActionsView(
            hasBet: true,
            canDeal: false,
            amountNeededForMinimum: 25,
            onClear: {},
            onDeal: {}
        )
    }
}

#Preview("Ready to Deal") {
    ZStack {
        Color.CasinoTable.felt.ignoresSafeArea()
        BettingActionsView(
            hasBet: true,
            canDeal: true,
            onClear: {},
            onDeal: {}
        )
    }
}

