import ComponentLibrary
import ComposableArchitecture
import SwiftUI

@Reducer
public struct BrandedAlertMultiButton {
    @ObservableState
    public struct State: Equatable {
        var style: MultiButtonAlertStyleUnified = .v1(.custom(.empty))

        public init(style: MultiButtonAlertStyleUnified) {
            self.style = style
        }

        // Convenience initializer for backwards compatibility - v1 by default
        public init(style: MultiButtonAlertStyle) {
            self.style = .v1(style)
        }

        public init() {
            self.style = .v1(.custom(.empty))
        }
    }

    public enum Action: BindableAction {
        case delegate(Delegate)
        case binding(BindingAction<State>)

        public enum Delegate {
            case tappedPrimaryButton
            case tappedSecondaryButton
        }
    }

    public init() {}

    public var body: some ReducerOf<Self> {
        BindingReducer()
        Reduce<State, Action> { _, action in
            switch action {
            case .delegate,
                 .binding:
                /* Catch-all */
                return .none
            }
        }
    }
}

public struct BrandedAlertMultiButtonView: View {
    @Bindable var store: StoreOf<BrandedAlertMultiButton>

    public init(store: StoreOf<BrandedAlertMultiButton>) {
        self.store = store
    }

    public var body: some View {
        VStack(spacing: .zero) {
            alertCopyStack
            ctaButton
        }
        .frame(width: isV2Style ? nil : 313)
        .background {
            isV2Style ? Color.SemanticV1.backgroundSecondary : Color.SemanticV1.backgroundPrimary
        }
        .environment(\.colorScheme, isV2Style ? .dark : .light)
        .clipShape(.rect(cornerRadius: 24))
        .shadow(radius: 10)
        .padding(.horizontal, isV2Style ? 32 : nil)
    }
}

private extension BrandedAlertMultiButtonView {
    var isV2Style: Bool {
        switch store.style {
        case .v1: return false
        case .v2: return true
        }
    }

    @ViewBuilder
    var alertCopyStack: some View {
        let textCopy = store.style.textCopy

        VStack(spacing: isV2Style ? 8 : .zero) {
            Text(textCopy.title)
                .typographyV1(isV2Style ? .titleText : .headline4)
                .foregroundStyle(Color.SemanticV1.textPrimary)
                .multilineTextAlignment(.center)
                .fixedSize(horizontal: false, vertical: true)
                .padding(.top, isV2Style ? 0 : 44)
                .padding(.bottom, isV2Style ? 0 : 16)

            Text(textCopy.description)
                .typographyV1(isV2Style ? .heading4.lineHeight(24) : .body3Book.lineHeight(5))
                .foregroundStyle(isV2Style ? Color.SemanticV1.textSecondary : Color.SemanticV1.iconBrand)
                .multilineTextAlignment(.center)
                .fixedSize(horizontal: false, vertical: true)
                .padding(.bottom, isV2Style ? 0 : 24)
        }
        .padding(.top, isV2Style ? 32 : 0)
        .padding(.bottom, isV2Style ? 16 : 0)
        .padding(.horizontal, isV2Style ? 32 : 16)
    }

    @ViewBuilder
    var ctaButton: some View {
        let textCopy = store.style.textCopy

        switch store.style {
        case .v2:
            HStack(spacing: 8) {
                Button {
                    store.send(.delegate(.tappedSecondaryButton))
                } label: {
                    Text(textCopy.secondaryButtonLabel)
                        .typographyV1(.subtitleLarge)
                        .foregroundStyle(Color.SemanticV1.textPrimary)
                        .frame(maxWidth: .infinity)
                        .padding(.vertical, 16)
                        .padding(.horizontal, 16)
                        .background(Color.SemanticV1.backgroundTertiary)
                        .clipShape(.capsule)
                }

                Button {
                    store.send(.delegate(.tappedPrimaryButton))
                } label: {
                    Text(textCopy.primaryButtonLabel)
                        .typographyV1(.subtitleLarge)
                        .foregroundStyle(Color.SemanticV1.backgroundPrimary)
                        .frame(maxWidth: .infinity)
                        .padding(.vertical, 16)
                        .padding(.horizontal, 16)
                        .background(Color.SemanticV1.textPrimary)
                        .clipShape(.capsule)
                }
            }
            .padding(.horizontal, isV2Style ? 32 : 20)
            .padding(.bottom, isV2Style ? 32 : 20)

        case .v1:
            HStack(spacing: 1) {
                Button {
                    store.send(.delegate(.tappedSecondaryButton))
                } label: {
                    ZStack {
                        Color.SemanticV1.backgroundPrimary
                        Text(textCopy.secondaryButtonLabel)
                            .typographyV1(.button1)
                            .foregroundStyle(Color.SemanticV1.textPrimary)
                    }
                }
                .contentShape(.rect)
                .frame(height: 56)
                .background {
                    Color.clear
                }

                Button {
                    store.send(.delegate(.tappedPrimaryButton))
                } label: {
                    ZStack {
                        Color.SemanticV1.backgroundPrimary
                        Text(textCopy.primaryButtonLabel)
                            .typographyV1(.button1)
                            .foregroundStyle(Color.SemanticV1.textPrimary)
                    }
                }
                .contentShape(.rect)
                .frame(height: 56)
                .background {
                    Color.clear
                }
            }
            .padding(.top, 1)
            .background {
                Color.black.opacity(0.15)
            }
        }
    }
}

private extension TypographyV1 {
    static let titleText: TypographyV1 = .init(
        name: "Title text",
        size: 18,
        style: .body,
        weight: .neueMontrealMedium,
        kerning: 0.36,
        lineHeight: 24
    )
}
