import CoreMedia
import Defaults
import Foundation

struct PlayerQueueItemBridge: Defaults.Bridge {
    typealias Value = PlayerQueueItem
    typealias Serializable = [String: String]

    func serialize(_ value: Value?) -> Serializable? {
        guard let value else {
            return nil
        }

        var playbackTime = ""
        if let time = value.playbackTime {
            if time.seconds.isFinite {
                playbackTime = String(time.seconds)
            }
        }

        var videoDuration = ""
        if let duration = value.videoDuration {
            if duration.isFinite {
                videoDuration = String(duration)
            }
        }

        var localURL = ""
        if let video = value.video, video.isLocal {
            localURL = video.localStream?.localURL.absoluteString ?? ""
        }

        return [
            "localURL": localURL,
            "videoID": value.videoID,
            "app": (value.app ?? value.video.app)?.rawValue ?? "",
            "instanceURL": (value.instanceURL ?? value.video.instanceURL)?.absoluteString ?? "",
            "playbackTime": playbackTime,
            "videoDuration": videoDuration
        ]
    }

    func deserialize(_ object: Serializable?) -> Value? {
        guard let object else { return nil }

        var app: VideosApp?
        var instanceURL: URL?
        var playbackTime: CMTime?
        var videoDuration: TimeInterval?

        if let time = object["playbackTime"],
           !time.isEmpty,
           let seconds = TimeInterval(time)
        {
            playbackTime = .secondsInDefaultTimescale(seconds)
        }

        if let duration = object["videoDuration"],
           !duration.isEmpty
        {
            videoDuration = TimeInterval(duration)
        }

        if let appString = object["app"],
           !appString.isEmpty
        {
            app = VideosApp(rawValue: appString)
        }

        if let url = object["instanceURL"]?.url {
            instanceURL = url
        }

        if let localUrlString = object["localURL"],
           !localUrlString.isEmpty,
           let localURL = URL(string: localUrlString)
        {
            return PlayerQueueItem(
                .local(localURL),
                playbackTime: playbackTime,
                videoDuration: videoDuration
            )
        }

        guard let videoID = object["videoID"] else { return nil }

        return PlayerQueueItem(
            .init(app: app ?? .local, instanceURL: instanceURL, videoID: videoID),
            videoID: videoID,
            app: app,
            instanceURL: instanceURL,
            playbackTime: playbackTime,
            videoDuration: videoDuration
        )
    }
}
