import AVFoundation
import NitroModules

/// NowPlayingPort — Hexagonal port interface for lock screen / notification
/// / Bluetooth now-playing display and remote command handling.
///
/// The engine pushes all data via explicit method calls. The implementation
/// handles all platform specifics (MPNowPlayingInfoCenter, MPRemoteCommandCenter,
/// artwork fetching, deduplication, etc.) with zero back-reference to the engine.
///
/// The default implementation is MPNowPlayingAdapter. This port can be
/// extracted to a separate package in the future.
///
/// Threading: all methods must be called on the main thread.
protocol NowPlayingPort: AnyObject {
    // MARK: - Remote Command Callback

    /// Called when a remote command is received (play, pause, skip, seek, etc.).
    /// The engine bridge handles default actions and JS notification.
    var onRemoteCommand: ((_ command: RemoteCommand, _ positionMs: Double?,
                           _ intervalMs: Double?) -> Void)? { get set }

    // MARK: - Configuration

    /// Set which remote commands are enabled on the lock screen / notification.
    func setEnabledCommands(_ commands: [RemoteCommand])

    /// Set the skip forward/backward interval in seconds.
    func setSkipInterval(_ seconds: Double)

    /// Mark a command as overridden by JS (suppresses native default action).
    func overrideCommand(_ command: RemoteCommand)

    /// Remove a JS override, restoring the native default action.
    func clearCommandOverride(_ command: RemoteCommand)

    /// Whether a command is currently overridden by JS.
    func isCommandOverridden(_ command: RemoteCommand) -> Bool

    // MARK: - State (pushed from engine)

    /// Called when the playback state changes.
    func handleStateChange(_ state: PlaybackState)

    /// Called when the current track's metadata changes.
    func updateMetadata(_ metadata: MPNowPlayingAdapter.TrackMetadata)

    /// Called on periodic time updates.
    func updateTime(_ time: MPNowPlayingAdapter.TimeInfo)

    /// Called when the playback rate changes.
    func updateRate(_ rate: Double)

    /// Called when JS sets manual now-playing info.
    func updateNowPlayingInfo(_ info: NowPlayingInfo)

    // MARK: - Ad Mode

    /// Set the AVPlayer reference for ad mode playhead tracking.
    func setAVPlayerForAdMode(_ player: AVPlayer?)

    /// Enter ad mode: lock screen shows ad title and duration.
    func setAdMode(title: String, durationSeconds: Double)

    /// Exit ad mode: restore content metadata on lock screen.
    func clearAdMode()

    /// Force a metadata refresh (e.g., after ad mode exit).
    func forceRefreshMetadata()

    // MARK: - Lifecycle

    /// Tear down all resources (command targets, artwork cache, etc.).
    func teardown()
}
