import APIClient
import AsyncAlgorithms
import ComponentLibrary
import ComposableArchitecture
import FeatureHooksModels
import Foundation
import StatsigClient
import Utilities

@DependencyClient
public struct NavigationRouterClient {
    public var send: (_ route: Route) -> Void
    // TODO: Remove all instances of this call
    public var sendIfNavV2: (_ route: Route, _ else: () -> Void) -> Void
    public var getChannel: () -> AsyncChannel<Route> = { AsyncChannel() }

    public enum Route {
        case explore
        case library(tooltipToShow: Tooltip?, showNewClips: Bool)
        case notifications
        case profile(_ handle: String, displayName: String? = nil, avatarImageUrl: String? = nil, recommendationMetadata: HooksRecommendationMetadata? = nil, simpleProfile: SimpleProfile? = nil)
        case playlist(_ playlist: Playlist)
        case playlistWithId(_ playlistId: String, title: String? = nil, imageUrl: String? = nil)
        case playlistSection(_ playlistSection: PlaylistSection)
        case trendingPlaylistSection(_ playlistSection: PlaylistSection)
        case playlistListSection(_ playlistListSection: PlaylistListSection)
        case genreDetailSection(_ styleItem: StyleItem)
        case hooksFeed
        case hooksContextualFeed(_ hooks: [Hook], _ startIndex: Int, _ navigationOptions: HookNavigationOptions?, _ source: HooksFeedSource)
        case myHooks(config: HooksGridConfig, likedHooksInitialState: HooksGridConfig.InitialState = .none)
        case userHooks(config: HooksGridConfig)
        case clipHooks(config: HooksGridConfig)
        case listenHistory
        case likedSongs
        case likedPlaylists
        case playlists
        case followingPlaylist
        case weeklyHitsPlaylist
        case creatorsToFollow
        case followers(handle: String)
        case following(handle: String)
        case settings
        case account
        case subscriptions
        case topUp
        case webView(title: String? = nil, url: URL)
        case search(SearchType)
        case remixesList(parentClip: Clip)
        case appearance
    }
}

extension NavigationRouterClient: DependencyKey {
    public static var liveValue: NavigationRouterClient {
        let channel = AsyncChannel<Route>()
        @Dependency(StatsigClient.self) var statsigClient

        func send(route: Route) {
            Task {
                await channel.send(route)
            }
        }

        return Self(
            send: { route in
                send(route: route)
            },
            sendIfNavV2: { route, _ in
                send(route: route)
            },
            getChannel: {
                channel
            }
        )
    }
}
