import Adamantium
import ComponentLibrary
import ComposableArchitecture
import StatsigClient
import SwiftUI

@Reducer
public struct DiscountAlertSingleButton {
    @ObservableState
    public struct State: Equatable {
        var style: DiscountAlertStyle

        init(style: DiscountAlertStyle) {
            self.style = style
        }

        var discountPercentage: Int {
            return 0 // Placeholder until we launch another promo
        }
    }

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

        public enum Delegate {
            case bringUpSubscribe
            case exitButton
        }
    }

    public init() {}

    @Dependency(StatsigClient.self) private var statsigClient

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

struct DiscountAlertSingleButtonView: View {
    @ObservedObject var circleMaskedAuraCoordinator = CircleMaskedAuraView.Coordinator()

    @ViewBuilder
    var auraView: some View {
        #if targetEnvironment(simulator)
            Color.black
        #else
            CircleMaskedAuraView(
                circleMaskedAuraCoordinator,
                morphSpeed: 0.013,
                scale: 2.0
            )
            .onAppear {
                applyPropertyTarget()
            }
        #endif
    }

    func applyPropertyTarget() {
        let propertyTarget = CircleMaskedAuraView.Coordinator.PropertyTarget(
            mainColorA: .init(x: 0.05490195, y: 0.05490195, z: 0.05490195),
            mainColorB: .init(x: 0.05490195, y: 0.05490195, z: 0.05490195),
            mainColorC: .init(x: 0.05490195, y: 0.05490195, z: 0.05490195),
            darkColorA: .init(x: 0.05490195, y: 0.05490195, z: 0.05490195),
            darkColorB: .init(x: 0.07673397, y: 0.07673397, z: 0.07673397),
            darkColorC: .init(x: 0.117168404, y: 0.117168404, z: 0.117168404),
            maskPosX: 0.453,
            maskPosY: 0.928,
            maskEdgeFade: 0.661,
            maskMinValueScalar: 0.0,
            maskRadius: 0.4
        )

        circleMaskedAuraCoordinator.setGradientSeed(.zero)
        circleMaskedAuraCoordinator.applyPropertiesWithoutTransitionAnimation(propertyTarget)
        circleMaskedAuraCoordinator.setPropertyTarget(propertyTarget)
    }

    @Bindable var store: StoreOf<DiscountAlertSingleButton>

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

    var body: some View {
        ZStack {
            // Background layer
            Color.clear
                .background {
                    auraView
                    Color.clear
                        .background(
                            LinearGradient(
                                stops: [
                                    Gradient.Stop(color: Color.SemanticV1.backgroundBlockOverlay.opacity(0), location: 0.00),
                                    Gradient.Stop(color: Color.SemanticV1.backgroundBlockOverlay.opacity(0.8), location: 1.00),
                                ],
                                startPoint: UnitPoint(x: 0.5, y: 0),
                                endPoint: UnitPoint(x: 0.5, y: 1.0)
                            )
                        )
                }
            VStack(spacing: 0) {
                exitButtonStack
                    .padding(.bottom, -14)
                copyStack
                    .padding(.bottom, 10)
                ctaButton
            }
            .environment(\.colorScheme, .light)
        }
        .frame(width: 313.0)
        .fixedSize(horizontal: false, vertical: true)
        .clipShape(.rect(cornerRadius: 24.0))
        .onTapGesture {
            switch tapAction {
            case .dismissOnly:
                store.send(.delegate(.exitButton))
            case .openSubscriptionPage:
                store.send(.delegate(.bringUpSubscribe))
            }
        }
    }
}

private extension DiscountAlertSingleButtonView {
    enum Constants {
        static let exitCircleSize: CGFloat = 40.0
        static let exitButtonPadding: CGFloat = 12.0
    }

    var copyData: DiscountAlertStyle.TextCopy {
        return store.style.textCopy(discountPercentage: store.discountPercentage)
    }

    var tapAction: DiscountAlertStyle.TapAction {
        return store.style.tapAction
    }

    @ViewBuilder
    var copyStack: some View {
        ZStack {
            switch store.style {
            case .preset(.proMonthly),
                 .preset(.premierMonthly),
                 .preset(.proYearly),
                 .preset(.premierYearly),
                 .preset(.catchAll):
                copyStackConsolidated
            }
        }
    }

    @ViewBuilder
    var copyStackConsolidated: some View {
        VStack(spacing: 24) {
            VStack(spacing: 12) {
                Image.Assets.discountPercentage
                    .resizable()
                    .scaledToFit()
                    .frame(width: 22, height: 22)
                Text(copyData.promotionName)
                    .typographyV1(.caption4.neueMontrealMedium())
                    .padding(.horizontal, 32.0)
                    .multilineTextAlignment(.center)
                    .foregroundStyle(Color.SemanticV1.textOnDark)
                    .fixedSize(horizontal: false, vertical: true)
            }
            (
                Text(copyData.promotionHeadline)
                    .foregroundStyle(Color.SemanticV1.textOnDark)
                    + Text(" ")
                    + Text(copyData.promotionHeadlineEmphasized)
                    .foregroundStyle(Color.SemanticV1.discountAccent)
            )
            .typographyV1(.headline1)
            .multilineTextAlignment(.center)
            .foregroundStyle(Color.SemanticV1.v4Accent)
            .padding(.horizontal, 10)
            .fixedSize(horizontal: false, vertical: true)
            Text(copyData.promotionDescription)
                .typographyV1(.body1.size { _ in 14 }.lineHeight(20))
                .multilineTextAlignment(.center)
                .foregroundStyle(Color.SemanticV1.textOnDark)
                .padding(.horizontal, 36)
                .padding(.bottom, 18)
                .fixedSize(horizontal: false, vertical: true)
        }
    }

    @ViewBuilder
    var ctaButton: some View {
        VStack {
            Spacer()
            Button {
                switch tapAction {
                case .dismissOnly:
                    store.send(.delegate(.exitButton))
                case .openSubscriptionPage:
                    store.send(.delegate(.bringUpSubscribe))
                }

            } label: {
                ZStack {
                    Color.SemanticV1.backgroundPrimary
                    Text(copyData.buttonCopy)
                        .typographyV1(.button1)
                        .foregroundStyle(Color.SemanticV1.textPrimary)
                }
            }
            .contentShape(.rect)
            .frame(height: 56.0)
            .background {
                Color.clear
            }
            .padding(.top, 1.0)
            .background {
                Color.black.opacity(0.15)
            }
        }
    }

    @ViewBuilder
    var tinyStar: some View {
        Image.Assets.v4StarDot
            .resizable()
            .scaledToFit()
            .frame(width: 8.0)
    }

    @ViewBuilder
    var exitButtonStack: some View {
        VStack {
            HStack {
                Spacer()
                Button {
                    store.send(.delegate(.exitButton))
                } label: {
                    ZStack {
                        Circle()
                            .fill(Color.SemanticV1.backgroundPrimary)
                            .frame(width: Constants.exitCircleSize, height: Constants.exitCircleSize)
                        Image.Icon.close
                            .foregroundStyle(Color.SemanticV1.textPrimary)
                    }
                    .padding(.top, Constants.exitButtonPadding)
                    .padding(.trailing, Constants.exitButtonPadding)
                }
            }
            Spacer()
        }
    }
}
