import APIClient
import Utilities
import DeeplinkIntents

public extension EventBusClient {
    enum OmniPlayerEvent {
        case setExpanded(Bool)
        case playClip(_ clip: Clip, queue: [Clip], context: SessionContext)
        case present(_ clip: Clip, autoPlay: Bool, context: SessionContext)
        case refresh
    }

    enum CreateEvent {
        case createClip(prompt: Prompt? = nil, didUseAppShortcut: Bool = false)
        case remasterClip(_ clip: Clip)
        case extendClip(_ clip: Clip, prompt: Prompt, hook: Hook? = nil)
        case coverClip(_ clip: Clip, prompt: Prompt, hook: Hook? = nil)
        case reusePrompt(prompt: Prompt)
        case getFullClip(_ clip: Clip)
        case showRemixActions(clip: Clip, hook: Hook? = nil)

        public enum TabId: String {
            case text
            case camera
            case audio
        }
    }

    // We should investigate migrating core models to SwiftData.
    // @Shared isn't useful for shared reads and writes to dynamic data i.e. different playlists and clips and profiles
    // For now, these events are more in-line with the in-memory screen-based
    // strategy we already have.
    // Unfortunately, without some more additions to the Event Bus architecture
    // we have to be very careful in avoiding infinite recursion with pub-sub
    // updates to objects.
    // This trivial integration will baseline result in double calls in objects that
    // both publish and subscribe to the same channel
    // TODO: Next short-term step outside of SwiftData models is to lock down the pub-sub to prevent a publisher from sending an event to itself. This is slightly involved and could use more abstraction / thought.
    enum ClipEvent {
        case updateClip(Clip)
        case removeClip(Clip)
        case removeClipFromPlaylist(Clip, playlist: Playlist)
        case toggledLike(Clip)
        case undoDeleteClip(Clip)
        case showSongActions(clip: Clip, playlist: Playlist?)
        case publishClip(Clip)
        // These events seem a bit more complicated to implement. They also don't
        // represent a regression as Nav V1 actually doesn't handle these events
        // without a full refresh anyways.
//        case restoreClip(Clip)
//        case addClipToPlaylist(Clip, playlist: Playlist)
    }

    enum BillingEvent {
        case billingInfoUpdated(SubscriptionInfoResponse)
    }

    enum HookEvent {
        case triggeredHookCreation(Hook) // Fired immediately when hook creation is initiated
        case hookCreated(hook: Hook) // Fired after hook is rendered and passes moderation
        case hookReported(hookId: String)
        case showReportedHook(hookId: String)
        case hookDeleted(hookId: String)
        case hookUpdated(Hook)
        case showHooksMoreMenu(Hook, source: HooksFeedSource? = nil)
        case showCreateHook(with: Clip? = nil)
        case shareHook(Hook, source: HooksFeedSource? = nil)
        case creatorHidden(hookId: String, handle: String)
        case showHideCreatorAlert(hook: Hook, source: HooksFeedSource? = nil)
        case confirmHideCreator(hook: Hook, source: HooksFeedSource? = nil)
        case hookLiked(hook: Hook)
        case hookUnliked(hookId: String)
        case hookDisliked(hookId: String)
        case hookUndisliked(hookId: String)
        case hookCommentsToggled(hookId: String, canComment: Bool)
        case pauseCurrentHook(cause: HookPauseCause)
        case playCurrentHook(cause: HookPlayCause)
        case showHookStatusPopup(reasons: [String])
        case showPublishSongAlert(hook: Hook)
    }

    enum ProfileEvent {
        case profileUpdated(Profile)
    }

    enum ModalEvent {
        case showModals(modals: [Modal])
    }
    
    enum DeeplinkEvent {
        case handleDeeplink(DeeplinkIntent)
    }
}
