//
//  SettingsComponents.swift
//  CasinoKit
//
//  Reusable settings UI components for casino games.
//

import SwiftUI

// MARK: - Settings Toggle

/// A toggle setting row with title and subtitle.
public struct SettingsToggle: View {
    /// The main title text.
    public let title: String
    
    /// The subtitle/description text.
    public let subtitle: String
    
    /// Binding to the toggle state.
    @Binding public var isOn: Bool
    
    /// The accent color for the toggle.
    public let accentColor: Color
    
    /// Creates a settings toggle.
    /// - Parameters:
    ///   - title: The main title.
    ///   - subtitle: The subtitle description.
    ///   - isOn: Binding to toggle state.
    ///   - accentColor: The accent color (default: yellow).
    public init(title: String, subtitle: String, isOn: Binding<Bool>, accentColor: Color = .yellow) {
        self.title = title
        self.subtitle = subtitle
        self._isOn = isOn
        self.accentColor = accentColor
    }
    
    public var body: some View {
        Toggle(isOn: $isOn) {
            VStack(alignment: .leading, spacing: CasinoDesign.Spacing.xxSmall) {
                Text(title)
                    .font(.system(size: CasinoDesign.BaseFontSize.medium, weight: .medium))
                    .foregroundStyle(.white)
                
                Text(subtitle)
                    .font(.system(size: CasinoDesign.BaseFontSize.body))
                    .foregroundStyle(.white.opacity(CasinoDesign.Opacity.medium))
            }
        }
        .tint(accentColor)
        .padding(.vertical, CasinoDesign.Spacing.xSmall)
    }
}

// MARK: - Speed Picker

/// A segmented picker for animation speed (Fast/Normal/Slow).
public struct SpeedPicker: View {
    /// Binding to the speed value (0.5 = fast, 1.0 = normal, 2.0 = slow).
    @Binding public var speed: Double
    
    /// The accent color for the selected button.
    public let accentColor: Color
    
    private let options: [(String, Double)] = [
        ("Fast", 0.5),
        ("Normal", 1.0),
        ("Slow", 2.0)
    ]
    
    /// Creates a speed picker.
    /// - Parameters:
    ///   - speed: Binding to the speed multiplier.
    ///   - accentColor: The accent color (default: yellow).
    public init(speed: Binding<Double>, accentColor: Color = .yellow) {
        self._speed = speed
        self.accentColor = accentColor
    }
    
    public var body: some View {
        VStack(alignment: .leading, spacing: CasinoDesign.Spacing.small) {
            Text(String(localized: "Dealing Speed", bundle: .module))
                .font(.system(size: CasinoDesign.BaseFontSize.medium, weight: .medium))
                .foregroundStyle(.white)
            
            HStack(spacing: CasinoDesign.Spacing.small) {
                ForEach(options, id: \.1) { option in
                    Button {
                        speed = option.1
                    } label: {
                        Text(option.0)
                            .font(.system(size: CasinoDesign.BaseFontSize.body, weight: .medium))
                            .foregroundStyle(speed == option.1 ? .black : .white.opacity(CasinoDesign.Opacity.strong))
                            .padding(.vertical, CasinoDesign.Spacing.small)
                            .frame(maxWidth: .infinity)
                            .background(
                                Capsule()
                                    .fill(speed == option.1 ? accentColor : Color.white.opacity(CasinoDesign.Opacity.subtle))
                            )
                    }
                    .buttonStyle(.plain)
                }
            }
        }
        .padding(.vertical, CasinoDesign.Spacing.xSmall)
    }
}

// MARK: - Volume Picker

/// A volume slider with speaker icons.
public struct VolumePicker: View {
    /// Binding to the volume level (0.0 to 1.0).
    @Binding public var volume: Float
    
    /// The accent color for the slider.
    public let accentColor: Color
    
    /// Creates a volume picker.
    /// - Parameters:
    ///   - volume: Binding to volume (0.0-1.0).
    ///   - accentColor: The accent color (default: yellow).
    public init(volume: Binding<Float>, accentColor: Color = .yellow) {
        self._volume = volume
        self.accentColor = accentColor
    }
    
    public var body: some View {
        VStack(alignment: .leading, spacing: CasinoDesign.Spacing.small) {
            HStack {
                Text(String(localized: "Volume", bundle: .module))
                    .font(.system(size: CasinoDesign.BaseFontSize.medium, weight: .medium))
                    .foregroundStyle(.white)
                
                Spacer()
                
                Text("\(Int(volume * 100))%")
                    .font(.system(size: CasinoDesign.BaseFontSize.body, weight: .medium, design: .rounded))
                    .foregroundStyle(.white.opacity(CasinoDesign.Opacity.medium))
            }
            
            HStack(spacing: CasinoDesign.Spacing.medium) {
                Image(systemName: "speaker.fill")
                    .font(.system(size: CasinoDesign.BaseFontSize.body))
                    .foregroundStyle(.white.opacity(CasinoDesign.Opacity.medium))
                
                Slider(value: $volume, in: 0...1, step: 0.1)
                    .tint(accentColor)
                
                Image(systemName: "speaker.wave.3.fill")
                    .font(.system(size: CasinoDesign.BaseFontSize.body))
                    .foregroundStyle(.white.opacity(CasinoDesign.Opacity.medium))
            }
        }
        .padding(.vertical, CasinoDesign.Spacing.xSmall)
    }
}

// MARK: - Selectable Row

/// A card-like selectable row with title, subtitle, optional badge, and selection indicator.
/// Use this for settings pickers like table limits, deck count, game style, etc.
public struct SelectableRow<Badge: View>: View {
    /// The main title text.
    public let title: String
    
    /// The subtitle/description text.
    public let subtitle: String
    
    /// Whether this row is currently selected.
    public let isSelected: Bool
    
    /// Optional badge view (e.g., a pill showing "$10 - $1,000").
    public let badge: Badge?
    
    /// The accent color for selection highlighting.
    public let accentColor: Color
    
    /// Action when tapped.
    public let action: () -> Void
    
    /// Creates a selectable row.
    /// - Parameters:
    ///   - title: The main title.
    ///   - subtitle: The subtitle description.
    ///   - isSelected: Whether this row is selected.
    ///   - accentColor: Color for selection (default: yellow).
    ///   - badge: Optional badge view.
    ///   - action: Action when tapped.
    public init(
        title: String,
        subtitle: String,
        isSelected: Bool,
        accentColor: Color = .yellow,
        @ViewBuilder badge: () -> Badge? = { nil as EmptyView? },
        action: @escaping () -> Void
    ) {
        self.title = title
        self.subtitle = subtitle
        self.isSelected = isSelected
        self.accentColor = accentColor
        self.badge = badge()
        self.action = action
    }
    
    public var body: some View {
        Button(action: action) {
            HStack {
                VStack(alignment: .leading, spacing: CasinoDesign.Spacing.xxSmall) {
                    Text(title)
                        .font(.system(size: CasinoDesign.BaseFontSize.large, weight: .semibold))
                        .foregroundStyle(.white)
                    
                    Text(subtitle)
                        .font(.system(size: CasinoDesign.BaseFontSize.body))
                        .foregroundStyle(.white.opacity(CasinoDesign.Opacity.medium))
                }
                
                Spacer()
                
                if let badge = badge {
                    badge
                }
                
                SelectionIndicator(isSelected: isSelected, accentColor: accentColor)
            }
            .padding()
            .background(
                RoundedRectangle(cornerRadius: CasinoDesign.CornerRadius.medium)
                    .fill(isSelected ? accentColor.opacity(CasinoDesign.Opacity.subtle) : Color.clear)
            )
            .overlay(
                RoundedRectangle(cornerRadius: CasinoDesign.CornerRadius.medium)
                    .strokeBorder(
                        isSelected ? accentColor.opacity(CasinoDesign.Opacity.medium) : Color.white.opacity(CasinoDesign.Opacity.subtle),
                        lineWidth: CasinoDesign.LineWidth.thin
                    )
            )
        }
        .buttonStyle(.plain)
    }
}

// Convenience initializer for rows without a badge
extension SelectableRow where Badge == EmptyView {
    /// Creates a selectable row without a badge.
    public init(
        title: String,
        subtitle: String,
        isSelected: Bool,
        accentColor: Color = .yellow,
        action: @escaping () -> Void
    ) {
        self.title = title
        self.subtitle = subtitle
        self.isSelected = isSelected
        self.accentColor = accentColor
        self.badge = nil
        self.action = action
    }
}

// MARK: - Selection Indicator

/// A circle indicator that shows selected (checkmark) or unselected (outline) state.
public struct SelectionIndicator: View {
    /// Whether the item is selected.
    public let isSelected: Bool
    
    /// The accent color for the checkmark.
    public let accentColor: Color
    
    /// The size of the indicator.
    public let size: CGFloat
    
    /// Creates a selection indicator.
    /// - Parameters:
    ///   - isSelected: Whether selected.
    ///   - accentColor: Color for checkmark (default: yellow).
    ///   - size: Size of the indicator (default: checkmark size from design).
    public init(
        isSelected: Bool,
        accentColor: Color = .yellow,
        size: CGFloat = CasinoDesign.Size.checkmark
    ) {
        self.isSelected = isSelected
        self.accentColor = accentColor
        self.size = size
    }
    
    public var body: some View {
        if isSelected {
            Image(systemName: "checkmark.circle.fill")
                .font(.system(size: size))
                .foregroundStyle(accentColor)
        } else {
            Circle()
                .strokeBorder(Color.white.opacity(CasinoDesign.Opacity.light), lineWidth: CasinoDesign.LineWidth.medium)
                .frame(width: size, height: size)
        }
    }
}

// MARK: - Badge Pill

/// A capsule-shaped badge for displaying values like "$10 - $1,000".
public struct BadgePill: View {
    /// The text to display in the badge.
    public let text: String
    
    /// Whether the parent row is selected.
    public let isSelected: Bool
    
    /// The accent color.
    public let accentColor: Color
    
    /// Creates a badge pill.
    /// - Parameters:
    ///   - text: The badge text.
    ///   - isSelected: Whether the parent row is selected.
    ///   - accentColor: Color for the badge (default: yellow).
    public init(text: String, isSelected: Bool, accentColor: Color = .yellow) {
        self.text = text
        self.isSelected = isSelected
        self.accentColor = accentColor
    }
    
    public var body: some View {
        Text(text)
            .font(.system(size: CasinoDesign.BaseFontSize.body, weight: .bold, design: .rounded))
            .foregroundStyle(isSelected ? .black : accentColor)
            .padding(.horizontal, CasinoDesign.Spacing.small)
            .padding(.vertical, CasinoDesign.Spacing.xSmall)
            .background(
                Capsule()
                    .fill(isSelected ? accentColor : accentColor.opacity(CasinoDesign.Opacity.hint))
            )
    }
}

// MARK: - Balance Picker

/// A grid picker for selecting a starting balance.
public struct BalancePicker: View {
    /// Binding to the selected balance.
    @Binding public var balance: Int
    
    /// The available balance options.
    public let options: [Int]
    
    /// The accent color for the selected button.
    public let accentColor: Color
    
    /// Creates a balance picker.
    /// - Parameters:
    ///   - balance: Binding to selected balance.
    ///   - options: Available balance options (default: standard values).
    ///   - accentColor: The accent color (default: yellow).
    public init(
        balance: Binding<Int>,
        options: [Int] = [1_000, 5_000, 10_000, 25_000, 50_000, 100_000],
        accentColor: Color = .yellow
    ) {
        self._balance = balance
        self.options = options
        self.accentColor = accentColor
    }
    
    public var body: some View {
        LazyVGrid(columns: [
            GridItem(.flexible()),
            GridItem(.flexible()),
            GridItem(.flexible())
        ], spacing: CasinoDesign.Spacing.small) {
            ForEach(options, id: \.self) { amount in
                Button {
                    balance = amount
                } label: {
                    Text(formattedAmount(amount))
                        .font(.system(size: CasinoDesign.BaseFontSize.body, weight: .bold))
                        .foregroundStyle(balance == amount ? .black : .white)
                        .padding(.vertical, CasinoDesign.Spacing.medium)
                        .frame(maxWidth: .infinity)
                        .background(
                            RoundedRectangle(cornerRadius: CasinoDesign.CornerRadius.small)
                                .fill(balance == amount ? accentColor : Color.white.opacity(CasinoDesign.Opacity.subtle))
                        )
                }
                .buttonStyle(.plain)
            }
        }
    }
    
    private func formattedAmount(_ amount: Int) -> String {
        if amount >= 1000 {
            return "$\(amount / 1000)K"
        }
        return "$\(amount)"
    }
}

#Preview {
    ScrollView {
        VStack(spacing: 20) {
            // Selectable rows
            VStack(spacing: CasinoDesign.Spacing.small) {
                SelectableRow(
                    title: "Low Stakes",
                    subtitle: "Standard mini table",
                    isSelected: true,
                    badge: { BadgePill(text: "$10 - $1,000", isSelected: true) },
                    action: {}
                )
                
                SelectableRow(
                    title: "Medium Stakes",
                    subtitle: "Regular casino table",
                    isSelected: false,
                    badge: { BadgePill(text: "$25 - $5,000", isSelected: false) },
                    action: {}
                )
                
                SelectableRow(
                    title: "6 Decks",
                    subtitle: "Standard casino shoe",
                    isSelected: false,
                    action: {}
                )
            }
            
            Divider().background(Color.white.opacity(0.1))
            
            SettingsToggle(
                title: "Sound Effects",
                subtitle: "Play sounds for game events",
                isOn: .constant(true)
            )
            
            Divider().background(Color.white.opacity(0.1))
            
            SpeedPicker(speed: .constant(1.0))
            
            Divider().background(Color.white.opacity(0.1))
            
            VolumePicker(volume: .constant(0.8))
            
            Divider().background(Color.white.opacity(0.1))
            
            BalancePicker(balance: .constant(10_000))
        }
        .padding()
    }
    .background(Color.Sheet.background)
}
