import ComposableArchitecture
import Foundation
import SwiftUI

public struct BrandedAlertView: View {
    @Bindable var store: StoreOf<BrandedAlert>

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

    public var body: some View {
        Color.SemanticV1.backgroundBlockOverlay
            .opacity(isAlertEnabled ? 0.75 : .zero)
            .transition(.opacity.animation(.easeOut.delay(store.alertStyle.animationDelay)))
            .animation(.easeIn, value: isAlertEnabled)
            .allowsHitTesting(isAlertEnabled)
            .onTapGesture {
                guard isAlertEnabled else { return }
                store.send(.dismissAlert(store.alertStyle))
            }
            .overlay {
                singleButtonAlert
                multiButtonAlert
                announceAlert
                listAlert
                featuredArtist
                versioningAlert
                discountAlert
                walkthroughAlert
                hookStatusAlert
            }
            .ignoresSafeArea()
    }
}

extension BrandedAlertStyle {
    var animationDelay: TimeInterval {
        switch self {
        case .noAlert:
            return 0.0
        case .announceAlert,
             .featuredArtist,
             .listAlert,
             .singleButtonAlert,
             .discountAlert,
             .walkthroughAlert:
            return 1.0
        case .versioningAlert, .multiButtonAlert, .hookStatusAlert:
            return 0.1
        }
    }
}

private extension BrandedAlertView {
    var isAlertEnabled: Bool {
        return store.alertStyle != .noAlert
    }

    @ViewBuilder
    var walkthroughAlert: some View {
        if let destinationStore = store.scope(state: \.destination?.walkthroughAlert, action: \.destination.walkthroughAlert) {
            BrandedAlertWalkthroughView(store: destinationStore)
                .transition(brandedAlertTransition)
        }
    }

    @ViewBuilder
    var hookStatusAlert: some View {
        if let destinationStore = store.scope(state: \.destination?.hookStatusAlert, action: \.destination.hookStatusAlert) {
            BrandedAlertHookStatusView(store: destinationStore)
                .transition(brandedAlertTransition)
        }
    }

    @ViewBuilder
    var discountAlert: some View {
        if let destinationStore = store.scope(state: \.destination?.discountAlert, action: \.destination.discountAlert) {
            DiscountAlertSingleButtonView(store: destinationStore)
                .transition(brandedAlertTransition)
        }
    }

    @ViewBuilder
    var versioningAlert: some View {
        if let destinationStore = store.scope(state: \.destination?.versioningAlert, action: \.destination.versioningAlert) {
            VersioningAlertSingleButtonView(store: destinationStore)
                .transition(brandedAlertTransition)
        }
    }

    @ViewBuilder
    var singleButtonAlert: some View {
        if let destinationStore = store.scope(state: \.destination?.singleButtonAlert, action: \.destination.singleButtonAlert) {
            BrandedAlertSingleButtonView(store: destinationStore)
                .transition(brandedAlertTransition)
        }
    }

    @ViewBuilder
    var multiButtonAlert: some View {
        if let destinationStore = store.scope(state: \.destination?.multiButtonAlert, action: \.destination.multiButtonAlert) {
            BrandedAlertMultiButtonView(store: destinationStore)
                .transition(brandedAlertTransition)
        }
    }

    @ViewBuilder
    var announceAlert: some View {
        if let destinationStore = store.scope(state: \.destination?.announceAlert, action: \.destination.announceAlert) {
            BrandedAlertAnnounceView(destinationStore)
                .transition(brandedAlertTransition)
        }
    }

    @ViewBuilder
    var listAlert: some View {
        if let destinationStore = store.scope(state: \.destination?.listAlert, action: \.destination.listAlert) {
            BrandedAlertListView(store: destinationStore)
                .transition(brandedAlertTransition)
        }
    }

    @ViewBuilder
    var featuredArtist: some View {
        if let destinationStore = store.scope(state: \.destination?.featuredArtist, action: \.destination.featuredArtist) {
            BrandedAlertFeaturedArtistView(store: destinationStore)
        }
    }

    var brandedAlertTransition: AnyTransition {
        return .asymmetric(
            insertion:
            .scale(
                scale: 0.9,
                anchor: .center
            )
            .combined(with: .opacity)
            .animation(.spring(
                response: 0.5,
                dampingFraction: 0.525,
                blendDuration: 0.1
            )
            ),
            removal:
            .opacity.animation(.easeOut)
        )
    }
}
