import AVKit
import Defaults
import Foundation
import SwiftUI

final class PiPDelegate: NSObject, AVPictureInPictureControllerDelegate {
    var player: PlayerModel { .shared }

    func pictureInPictureController(
        _: AVPictureInPictureController,
        failedToStartPictureInPictureWithError error: Error
    ) {
        print(error.localizedDescription)
    }

    func pictureInPictureControllerWillStartPictureInPicture(_: AVPictureInPictureController) {}

    func pictureInPictureControllerDidStartPictureInPicture(_: AVPictureInPictureController) {
        player.play()

        player.playingInPictureInPicture = true
        player.avPlayerBackend.startPictureInPictureOnPlay = false
        player.avPlayerBackend.startPictureInPictureOnSwitch = false
        player.controls.objectWillChange.send()

        if Defaults[.closePlayerOnOpeningPiP] { Delay.by(0.1) { self.player.hide() } }
    }

    func pictureInPictureControllerDidStopPictureInPicture(_: AVPictureInPictureController) {
        player.playingInPictureInPicture = false
        player.controls.objectWillChange.send()
    }

    func pictureInPictureControllerWillStopPictureInPicture(_: AVPictureInPictureController) {
        player.show()
    }

    func pictureInPictureController(
        _: AVPictureInPictureController,
        restoreUserInterfaceForPictureInPictureStopWithCompletionHandler completionHandler: @escaping (Bool) -> Void
    ) {
        let wasPlaying = player.isPlaying

        var delay = 0.0
        #if os(iOS)
            if !player.presentingPlayer {
                delay = 0.5
            }
            if player.currentItem.isNil {
                delay = 1
            }
        #endif

        if !player.currentItem.isNil, !player.musicMode {
            player.show()
        }

        DispatchQueue.main.asyncAfter(deadline: .now() + delay) { [weak self] in
            withAnimation(.linear(duration: 0.3)) {
                self?.player.playingInPictureInPicture = false
            }

            if wasPlaying {
                Delay.by(1) {
                    self?.player.play()
                }
            }
            completionHandler(true)
        }
    }
}