import Foundation
import SwiftUI

public struct AuraButton<LeadingView: View>: View {
    private let title: String
    private let isLoading: Bool
    private let auraStyle: ButtonAuraBackground.AuraStyle
    private let withGradientOverlay: Bool
    private let leadingView: LeadingView
    private let action: () -> Void

    @Environment(\.pillButtonSizeV1) private var size
    @Environment(\.isEnabled) private var isEnabled

    public init(
        title: String = "",
        isLoading: Bool = false,
        auraStyle: ButtonAuraBackground.AuraStyle,
        withGradientOverlay: Bool = true,
        @ViewBuilder leadingView: () -> LeadingView,
        action: @escaping () -> Void
    ) {
        self.title = title
        self.isLoading = isLoading
        self.auraStyle = auraStyle
        self.withGradientOverlay = withGradientOverlay
        self.leadingView = leadingView()
        self.action = action
    }

    public var body: some View {
        Button {
            action()
        } label: {
            HStack {
                leadingView // need a solution here to allow .resizable and .aspectRatio(contentMode: .fit)
                    .frame(width: size.iconWidth, height: size.iconWidth)

                Text(title)
                    .accessibilityLabel(title)
            }
            .colorScheme(.dark)
        }
        .disabled(isLoading)
        .buttonStyle(
            PillButtonStyleV1(
                isLoading: isLoading,
                isEnabled: isEnabled,
                isIconOnly: false,
                size: size,
                colorCombination: auraButtonColorCombination
            )
        )
        .background(
            ButtonAuraBackground(style: auraStyle, withGradientOverlay: withGradientOverlay)
        )
        .clipShape(Capsule())
        .glassBorder(shape: .capsule, enabled: withGradientOverlay)
    }
}

public extension AuraButton where LeadingView == EmptyView {
    /// Create a primary button without a leading view.
    /// - Parameters:
    ///   - title: Centered title label
    ///   - isLoading: True to display a loading indicator instead of the label.
    ///   - action: Action to be triggered on tap
    init(
        title: String,
        isLoading: Bool = false,
        auraStyle: ButtonAuraBackground.AuraStyle,
        withGradientOverlay: Bool = true,
        action: @escaping () -> Void
    ) {
        self.init(
            title: title,
            isLoading: isLoading,
            auraStyle: auraStyle,
            withGradientOverlay: withGradientOverlay,
            leadingView: { EmptyView() },
            action: action
        )
    }
}

let auraButtonColorCombination = PillButtonStyleV1.ColorCombination(
    enabled: PillButtonStyleV1.ColorSet(
        foreground: .SemanticV1.textPrimary,
        background: Color.clear,
        loading: .SemanticV1.iconInvert,
        border: .clear
    ),
    pressed: PillButtonStyleV1.ColorSet(
        foreground: .SemanticV1.textPrimary.opacity(0.5),
        background: .SemanticV1.backgroundPrimary.opacity(0.3),
        loading: .SemanticV1.iconInvert,
        border: .clear
    ),
    disabled: PillButtonStyleV1.ColorSet(
        foreground: .SemanticV1.textPrimary.opacity(0.5),
        background: .SemanticV1.backgroundPrimary.opacity(0.5),
        loading: .SemanticV1.iconInvert,
        border: .clear
    )
)

struct AuraButton_Previews: PreviewProvider {
    static var previews: some View {
        AuraButtonSample(title: "Button")
    }
}

struct AuraButtonSample: View {
    let title: String

    init(title: String) {
        self.title = title
    }

    var body: some View {
        VStack {
            AuraButton(
                title: title,
                auraStyle: .pink,
                action: {}
            )

            AuraButton(
                title: title,
                isLoading: false,
                auraStyle: .blue,
                leadingView: { Image(systemName: "globe") },
                action: {}
            )

            AuraButton(
                title: title,
                isLoading: true,
                auraStyle: .pink,
                leadingView: { Image(systemName: "globe") },
                action: {}
            )

            AuraButton(
                title: title,
                isLoading: false,
                auraStyle: .blue,
                leadingView: { Image(systemName: "globe") },
                action: {}
            )

            AuraButton(
                title: title,
                auraStyle: .pink,
                action: {}
            )
            .disabled(true)
        }
        .padding()
    }
}
