//
//  SidebarItem.swift
//  Yattee
//
//  Represents items that can appear in the sidebar navigation.
//

import Foundation

/// Represents all possible sidebar items for navigation.
enum SidebarItem: Hashable, Identifiable {
    // MARK: - Fixed Navigation Items
    case home
    case search
    case sources
    case settings
    case nowPlaying
    case openURL
    case remoteControl

    // MARK: - Dynamic Channel Items
    case channel(channelID: String, name: String, source: ContentSource)

    // MARK: - Dynamic Playlist Items
    case playlist(id: UUID, title: String)

    // MARK: - Dynamic Media Source Items
    case mediaSource(id: UUID, name: String, type: MediaSourceType)

    // MARK: - Dynamic Instance Items
    case instance(id: UUID, name: String, type: InstanceType)

    // MARK: - Collection Items
    case bookmarks
    case history
    case downloads
    case subscriptionsFeed
    case manageChannels
    case playlistsList
    case continueWatching

    // MARK: - Identifiable

    var id: String {
        switch self {
        case .home:
            return "home"
        case .search:
            return "search"
        case .sources:
            return "sources"
        case .settings:
            return "settings"
        case .nowPlaying:
            return "now-playing"
        case .openURL:
            return "open-url"
        case .remoteControl:
            return "remote-control"
        case .channel(let channelID, _, let source):
            return "channel-\(source.provider)-\(channelID)"
        case .playlist(let id, _):
            return "playlist-\(id.uuidString)"
        case .mediaSource(let id, _, _):
            return "mediasource-\(id.uuidString)"
        case .instance(let id, _, _):
            return "instance-\(id.uuidString)"
        case .bookmarks:
            return "bookmarks"
        case .history:
            return "history"
        case .downloads:
            return "downloads"
        case .subscriptionsFeed:
            return "subscriptions-feed"
        case .manageChannels:
            return "manage-channels"
        case .playlistsList:
            return "playlists-list"
        case .continueWatching:
            return "continue-watching"
        }
    }

    // MARK: - Display Properties

    var title: String {
        switch self {
        case .home:
            return String(localized: "tabs.home")
        case .search:
            return String(localized: "tabs.search")
        case .sources:
            return String(localized: "tabs.sources")
        case .settings:
            return String(localized: "tabs.settings")
        case .nowPlaying:
            return String(localized: "sidebar.nowPlaying")
        case .openURL:
            return String(localized: "sidebar.mainItem.openURL")
        case .remoteControl:
            return String(localized: "sidebar.mainItem.remoteControl")
        case .channel(_, let name, _):
            return name
        case .playlist(_, let title):
            return title
        case .mediaSource(_, let name, _):
            return name
        case .instance(_, let name, _):
            return name
        case .bookmarks:
            return String(localized: "home.bookmarks.title")
        case .history:
            return String(localized: "home.history.title")
        case .downloads:
            return String(localized: "home.downloads.title")
        case .subscriptionsFeed:
            return String(localized: "home.subscriptions.title")
        case .manageChannels:
            return String(localized: "sidebar.manageChannels")
        case .playlistsList:
            return String(localized: "home.playlists.title")
        case .continueWatching:
            return String(localized: "home.continueWatching.title")
        }
    }

    var systemImage: String {
        switch self {
        case .home:
            return "house.fill"
        case .search:
            return "magnifyingglass"
        case .sources:
            return "server.rack"
        case .settings:
            return "gear"
        case .nowPlaying:
            return "play.circle.fill"
        case .openURL:
            return "link"
        case .remoteControl:
            return "antenna.radiowaves.left.and.right"
        case .channel:
            return "person.circle"
        case .playlist:
            return "list.bullet.rectangle"
        case .mediaSource(_, _, let type):
            return type.systemImage
        case .instance(_, _, let type):
            return type.systemImage
        case .bookmarks:
            return "bookmark.fill"
        case .history:
            return "clock"
        case .downloads:
            return "arrow.down.circle"
        case .subscriptionsFeed:
            return "play.square.stack.fill"
        case .manageChannels:
            return "person.2"
        case .playlistsList:
            return "list.bullet.rectangle"
        case .continueWatching:
            return "play.circle"
        }
    }

    // MARK: - Navigation

    /// Converts this sidebar item to a NavigationDestination for pushing onto the navigation stack.
    /// Returns nil for items that are root views (home, search) which don't push.
    func navigationDestination() -> NavigationDestination? {
        switch self {
        case .home, .search, .sources, .settings, .nowPlaying, .openURL, .remoteControl:
            // These are root tabs, not push destinations
            return nil
        case .channel(let channelID, _, let source):
            return .channel(channelID, source)
        case .playlist(let id, let title):
            return .playlist(.local(id, title: title))
        case .mediaSource(let id, _, _):
            return .mediaSource(id)
        case .instance:
            // Instances are root views in the sidebar, not push destinations
            return nil
        case .bookmarks:
            return .bookmarks
        case .history:
            return .history
        case .downloads:
            return .downloads
        case .subscriptionsFeed:
            return .subscriptionsFeed
        case .manageChannels:
            return .manageChannels
        case .playlistsList:
            return .playlists
        case .continueWatching:
            return .continueWatching
        }
    }

    // MARK: - Item Categories

    /// Whether this is a fixed navigation item (always visible).
    var isFixedNavigation: Bool {
        switch self {
        case .home, .search, .sources, .settings, .nowPlaying, .openURL, .remoteControl:
            return true
        default:
            return false
        }
    }

    /// Whether this is a dynamic channel item.
    var isChannel: Bool {
        if case .channel = self { return true }
        return false
    }

    /// Whether this is a dynamic playlist item.
    var isPlaylist: Bool {
        if case .playlist = self { return true }
        return false
    }

    /// Whether this is a dynamic media source item.
    var isMediaSource: Bool {
        if case .mediaSource = self { return true }
        return false
    }

    /// Whether this is a dynamic instance item.
    var isInstance: Bool {
        if case .instance = self { return true }
        return false
    }
}

// MARK: - Factory Methods

extension SidebarItem {
    /// Creates a SidebarItem from a Subscription.
    static func from(subscription: Subscription) -> SidebarItem {
        .channel(
            channelID: subscription.channelID,
            name: subscription.name,
            source: subscription.contentSource
        )
    }

    /// Creates a SidebarItem from a LocalPlaylist.
    static func from(playlist: LocalPlaylist) -> SidebarItem {
        .playlist(id: playlist.id, title: playlist.title)
    }

    /// Creates a SidebarItem from a MediaSource.
    static func from(mediaSource: MediaSource) -> SidebarItem {
        .mediaSource(id: mediaSource.id, name: mediaSource.name, type: mediaSource.type)
    }

    /// Creates a SidebarItem from an Instance.
    static func from(instance: Instance) -> SidebarItem {
        .instance(id: instance.id, name: instance.displayName, type: instance.type)
    }
}
