//
//  MPPositive_SongViewModel.swift
//  MusicPlayer
//
//  Created by Mr.Zhou on 2024/5/8.
//

import UIKit
import AVKit
import AVFoundation
class MPPositive_SongViewModel: NSObject {
    ///排序号
    var index:Int!
    ///音乐资源路径
    var resourcePlayerItem:AVPlayerItem!
    ///资源加载路径
    var resourceAsset:AVURLAsset!
    ///封面
    var coverUrl:URL?
    ///标题
    var title:String?
    ///副标题
    var subtitle:String?
    ///歌词
    var lyrics:String?
    ///相关内容ID
    var relatedId:String?
    ///是否收藏
    var isCollection:Bool?
    ///是否下载
    var isDlownd:Bool?
    ///音乐实体
    var song:MPPositive_SongItemModel!
    ///是否进行过预加载
    var isPloading:Bool = false
    // 标记为已取消
    private var isCancelled = false
    init(_ song:MPPositive_SongItemModel) {
        super.init()
        self.song = song
        configure()
    }
    deinit {
        //释放内存
        resourcePlayerItem = nil
        resourceAsset = nil
        isCancelled = true
        print("\(title ?? "")被释放了")
    }
    //数据配置
    private func configure() {
        index = song.index
        //资源路径默认取第一条
        if song.resourceUrls?.first != nil, let first = URL(string: song.resourceUrls?.first ?? ""){
            //创建一个资产链接并允许它预加载
            resourceAsset = .init(url: first, options: [AVURLAssetPreferPreciseDurationAndTimingKey: true])
            //创建PlayerItem
            resourcePlayerItem = .init(asset: resourceAsset)
        }
        //封面路径默认取最后一条
        if song.reviewUrls?.first != nil {
            coverUrl = .init(string: song.reviewUrls!.last!)
        }
        //标题
        if song.title != nil {
            title = song.title!
        }
        //副标题(作者/专辑)
        if song.shortBylineText != nil {
            subtitle = song.shortBylineText!
        }
        //歌词
        if song.lyricsID != nil {
            //执行网络请求拿到歌词数据
            MP_NetWorkManager.shared.requestLyric(song.lyricsID!) {[weak self] lyrics in
                self?.lyrics = lyrics
            }
        }
        //相关内容
        if song.relatedID != nil {
            relatedId = song.relatedID
        }
        reloadCollectionAndDownLoad()
        //执行预加载
//        if isPloading == false {
//            preloadAsset(resourceAsset)
//        }
    }
    //页面状态更新
    func reloadCollectionAndDownLoad() {
        //检索是否收藏
        isCollection = MPPositive_CollectionSongModel.fetch(.init(format: "videoId == %@", song.videoId)).count != 0
        
        //检索是否下载
        isDlownd = MPPositive_DownloadItemModel.fetch(.init(format: "videoId == %@", song.videoId)).count != 0
    }
    
    //执行预加载
    func preloadAsset(_ asset:AVURLAsset) {
        guard isPloading == false else {
            return
        }
        self.isPloading = true
        //执行预加载
        if #available(iOS 16, *) {
            //ios16以上的情况
            Task{
                do{
                    let playable = try await asset.load(.isPlayable)
                    guard !isCancelled else {
                        return
                    }
                    if playable == true {
                        print("\(self.title ?? "")预加载成功")
                        self.isPloading = true
                    }else {
                        //检索预加载失败原因
                        switch asset.status(of: .isPlayable) {
                        case .failed(let erro):
                            print("\(title ?? "")预加载失败，失败原因:\(erro.localizedDescription)")
                            self.isPloading = false
                        default:
                            self.isPloading = false
                        }
                    }
                }catch{
                    print("预加载失败:\(error.localizedDescription)")
                }
            }
        }else {
            //ios16以下的情况
            let keys = ["playable"]
            asset.loadValuesAsynchronously(forKeys: keys) {
                [weak self] in
                guard let self = self, !isCancelled else {return}
                for key in keys {
                    var error: NSError? = nil
                    let status = asset.statusOfValue(forKey: key, error: &error)
                    switch status {
                    case .loaded:
                        // key成功加载，资源准备就绪
                        DispatchQueue.main.async {
                            print("\(self.title ?? "")预加载成功")
                            self.isPloading = true
                        }
                    case .failed:
                        print("\(title ?? "")预加载失败，失败原因:\(error?.localizedDescription ?? "")")
                        self.isPloading = false
                    case .cancelled:
                        print("\(title ?? "")预加载被取消了")
                        self.isPloading = false
                    default:
                        break
                    }
                }
            }
        }
    }
}
