import APIClient
import ComponentLibrary
import ComposableArchitecture
import FeatureHooksCreate
import FeatureHooksModels
import FeatureHooksPost
import FeatureToasts
import Foundation
import SwiftUI
import Utilities

// swiftlint:disable file_length

private let log = Logger(category: "HooksContextualFeedReducer")

@Reducer
public struct HooksContextualFeedReducer {
    @ObservableState
    public struct State: Equatable {
        @ObservationStateIgnored @ObservedBox var hooksFeed: HooksFeedReducer.State
        @Shared public var me: Me

        public var hook: Hook?
        public var hooks: [Hook]
        public var startIndex: Int
        public var navigationOptions: HookNavigationOptions?
        public init(
            me: Shared<Me>,
            hook: Hook? = nil,
            startIndex: Int,
            hooks: [Hook] = [],
            navigationOptions: HookNavigationOptions? = nil,
            source: HooksFeedSource = .unknown
        ) {
            self._me = me
            self.hook = hook
            self.startIndex = startIndex
            self.hooks = hooks
            self.navigationOptions = navigationOptions

            self.hooksFeed = HooksFeedReducer.State(
                me: me,
                initialHooks: hooks,
                startIndex: startIndex,
                source: source,
                navigationOptions: navigationOptions
            )
        }
    }

    public enum Action {
        case task
        case closeTapped
        case hooksFeed(HooksFeedReducer.Action)
    }

    @Dependency(\.dismiss) var dismiss
    @Dependency(\.hooksPlayerClient) var playerClient

    public init() {}

    public var body: some ReducerOf<Self> {
        Scope(state: \.hooksFeed, action: \.hooksFeed) {
            HooksFeedReducer()
        }
        Reduce<State, Action> { state, action in
            switch action {
            case .task:
                playerClient.setup(state.me.user.id)
                return .send(.hooksFeed(.task))

            case .closeTapped:
                return .run { _ in await self.dismiss() }

            case .hooksFeed(.delegate(.exitContextualFeed)):
                return .run { _ in await self.dismiss() }

            case .hooksFeed:
                return .none
            }
        }
    }
}

// MARK: - Analytics Debug Extensions

public extension HooksContextualFeedReducer.State {
    /// Debug description for analytics tracking
    var analyticsDebugDescription: String {
        let sourceInfo = hooksFeed.source.analyticsContext
        let navInfo = navigationOptions?.debugDescription ?? "None"
        let sourceUrl = (sourceInfo.contextType == "deeplink") ? sourceInfo.contextId : nil
        return """
        Hook: \(hook?.id ?? "none")
        Source: \(hooksFeed.source) → \(sourceInfo.contextType ?? "nil"):\(sourceInfo.contextId ?? "nil")
        SourceURL: \(sourceUrl ?? "nil")
        Navigation: \(navInfo)
        """
    }
}

public struct HooksContextualFeed: View {
    @Bindable var store: StoreOf<HooksContextualFeedReducer>
    public init(store: StoreOf<HooksContextualFeedReducer>) {
        self.store = store
    }

    public var body: some View {
        HooksFeedView(store: store.scope(state: \.hooksFeed, action: \.hooksFeed))
            .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
            .overlay(alignment: .bottom) {
                invertedRoundedCornerShape
            }
            .task {
                store.send(.task)
            }
            .background(Color.black.ignoresSafeArea())
            .ignoresSafeArea(edges: .top)
            .environment(\.colorScheme, .dark)
            .scrollEdgeEffect(hidden: true, for: .top)
            .toolbarBackgroundVisibility(.hidden, for: .navigationBar)
    }

    // Same thing we show on HooksTabBar when on the Hooks tab,
    // except we want to always show it when playing Hooks,
    // like in a contextual feed (profile, my hooks, etc.)
    private var invertedRoundedCornerShape: some View {
        Rectangle()
            .fill(Color.SemanticV1.backgroundPrimary)
            .frame(height: 30)
            .mask(alignment: .bottom) {
                Rectangle()
                    .overlay(alignment: .bottom) {
                        UnevenRoundedRectangle(
                            topLeadingRadius: 0,
                            bottomLeadingRadius: 30,
                            bottomTrailingRadius: 30,
                            topTrailingRadius: 0
                        )
                        .blendMode(.destinationOut)
                    }
            }
            .opacity(store.hooksFeed.isShowingOmniPlayer ? 0 : 1)
    }
}
