import ComponentLibrary
import ComposableArchitecture
import Foundation
import StatsigClient
import SwiftUI

/*
    I'm using this container as a sort of presenter,
    All the raw data is being converted into view models in the private extension.

    Along with pickin up some constantly available triggers (shake, notification)
 */
public struct DebugMenuView: View {
    @State var store: StoreOf<DebugMenu>
    private let actions: Actions

    public struct Actions {
        let showOnboarding: () -> Void
        let showMadlibsOnboarding: () -> Void
        let showHooksCreate: () -> Void
        let showNotificationQuestion: () -> Void
        let showOrpheusCustomCreate: () -> Void
        let showOrpheusCustomCreateCover: () -> Void

        public init(
            showOnboarding: @escaping () -> Void,
            showMadlibsOnboarding: @escaping () -> Void,
            showHooksCreate: @escaping () -> Void,
            showNotificationQuestion: @escaping () -> Void,
            showOrpheusCustomCreate: @escaping () -> Void,
            showOrpheusCustomCreateCover: @escaping () -> Void
        ) {
            self.showOnboarding = showOnboarding
            self.showMadlibsOnboarding = showMadlibsOnboarding
            self.showHooksCreate = showHooksCreate
            self.showNotificationQuestion = showNotificationQuestion
            self.showOrpheusCustomCreate = showOrpheusCustomCreate
            self.showOrpheusCustomCreateCover = showOrpheusCustomCreateCover
        }
    }

    public init(actions: Actions) {
        self.store = Store(initialState: .init(), reducer: { DebugMenu() })
        self.actions = actions
    }

    public var body: some View {
        if DebugMenu.isAllowed {
            ZStack {
                if store.isPanelShown {
                    DebugMenuPanelView(store: store)
                        .transition(.asymmetric(insertion: .move(edge: .trailing), removal: .opacity))
                } else {
                    EmptyView()
                }
            }
            .sheet(
                item: $store.scope(state: \.destination?.featureFlags, action: \.destination.featureFlags),
                onDismiss: { store.state.destination = .none },
                content: { _ in InternalFeatureFlagsDebugMenu() }
            )
            .sheet(
                item: $store.scope(state: \.destination?.internalViewPicker, action: \.destination.internalViewPicker),
                onDismiss: { store.state.destination = .none },
                content: { _ in
                    InternalViews(actions: .init(
                        showOnboarding: {
                            store.send(.closePanel(animated: false))
                            actions.showOnboarding()
                        },
                        showMadlibsOnboarding: {
                            store.send(.closePanel(animated: false))
                            actions.showMadlibsOnboarding()
                        },
                        showHooksCreate: {
                            store.send(.closePanel(animated: false))
                            actions.showHooksCreate()
                        },
                        showNotificationQuestion: {
                            store.send(.closePanel(animated: false))
                            actions.showNotificationQuestion()
                        },
                        showOrpheusCustomCreate: {
                            store.send(.closePanel(animated: false))
                            actions.showOrpheusCustomCreate()
                        },
                        showOrpheusCustomCreateCover: {
                            store.send(.closePanel(animated: false))
                            actions.showOrpheusCustomCreateCover()
                        }
                    ))
                }
            )
            .sheet(
                item: $store.scope(state: \.destination?.appStorageMenu, action: \.destination.appStorageMenu),
                onDismiss: { store.state.destination = .none },
                content: { appStorageStore in
                    AppStorageMenuView(store: appStorageStore)
                }
            )
            .alert($store.scope(state: \.destination?.alert, action: \.destination.alert))
            .onShake {
                store.send(.onShake)
            }
            .onAnalyticsTrackingDebugNotification { debugEvent in
                store.send(.addAnalyticsEvent(debugEvent))
            }
        } else {
            EmptyView()
        }
    }
}
