import Foundation
import MediaPlayer

/// Handles iOS Now Playing info center and remote command center for lock screen / Control Center controls.
@MainActor
final class MediaKeyHandler {

    static let shared = MediaKeyHandler()

    private weak var playerVM: PlayerViewModel?

    func register(playerVM: PlayerViewModel) {
        self.playerVM = playerVM
        setupRemoteCommands()
    }

    private func setupRemoteCommands() {
        let center = MPRemoteCommandCenter.shared()

        center.playCommand.isEnabled = true
        center.playCommand.addTarget { [weak self] _ in
            self?.playerVM?.togglePlayPause()
            return .success
        }

        center.pauseCommand.isEnabled = true
        center.pauseCommand.addTarget { [weak self] _ in
            self?.playerVM?.togglePlayPause()
            return .success
        }

        center.togglePlayPauseCommand.isEnabled = true
        center.togglePlayPauseCommand.addTarget { [weak self] _ in
            self?.playerVM?.togglePlayPause()
            return .success
        }

        center.nextTrackCommand.isEnabled = true
        center.nextTrackCommand.addTarget { [weak self] _ in
            self?.playerVM?.playNext()
            return .success
        }

        center.previousTrackCommand.isEnabled = true
        center.previousTrackCommand.addTarget { [weak self] _ in
            self?.playerVM?.playPrevious()
            return .success
        }

        center.changePlaybackPositionCommand.isEnabled = true
        center.changePlaybackPositionCommand.addTarget { [weak self] event in
            guard let event = event as? MPChangePlaybackPositionCommandEvent else { return .commandFailed }
            self?.playerVM?.seek(to: event.positionTime)
            return .success
        }

        center.skipForwardCommand.isEnabled = true
        center.skipForwardCommand.preferredIntervals = [10]
        center.skipForwardCommand.addTarget { [weak self] event in
            guard let event = event as? MPSkipIntervalCommandEvent else { return .commandFailed }
            self?.playerVM?.skipForward(event.interval)
            return .success
        }

        center.skipBackwardCommand.isEnabled = true
        center.skipBackwardCommand.preferredIntervals = [10]
        center.skipBackwardCommand.addTarget { [weak self] event in
            guard let event = event as? MPSkipIntervalCommandEvent else { return .commandFailed }
            self?.playerVM?.skipBackward(event.interval)
            return .success
        }
    }

    func updateNowPlaying(track: Track?, isPlaying: Bool, currentTime: TimeInterval, duration: TimeInterval) {
        var info = [String: Any]()
        info[MPMediaItemPropertyTitle] = track?.title ?? "MixBoard"
        info[MPMediaItemPropertyArtist] = track?.artist ?? ""
        info[MPMediaItemPropertyAlbumTitle] = track?.album ?? ""
        info[MPMediaItemPropertyPlaybackDuration] = duration
        info[MPNowPlayingInfoPropertyElapsedPlaybackTime] = currentTime
        info[MPNowPlayingInfoPropertyPlaybackRate] = isPlaying ? 1.0 : 0.0

        if let bpm = track?.bpm {
            info[MPMediaItemPropertyBeatsPerMinute] = Int(bpm)
        }

        MPNowPlayingInfoCenter.default().nowPlayingInfo = info
    }
}
