//
//  ZZHCustomPlayerForVideoTask.swift
//  SwiftProject
//
//  Created by aaa on 2024/4/17.
//

import Foundation
import AVFoundation
import Photos
import AVKit
import VideoToolbox

let CustomPlayerShareSemaphore = DispatchSemaphore(value: 1)

extension ZZHCustomPlayer {
    
    func getPlayerItem() -> AVPlayerItem {
        let temItem = AVPlayerItem(asset: self.videoOriginalAsset)
       AVVideoComposition.videoComposition(with: temItem.asset) { [weak self] request in
           
//           print("正在请求解码图片frame....")
           guard let weakSelf = self else {
               print("self 被销毁了.....")
               return
           }
//           CustomPlayerShareSemaphore.wait()
           weakSelf.convertFrame(request:request)
//           CustomPlayerShareSemaphore.signal()
           
        } completionHandler: { ac, err in
            if err != nil {
                print("初始化coposition报错：\(err)")
            }
            else{
                print("composition 生成ok....")
                temItem.videoComposition = ac
            }
        }
        return temItem
    }
    
//    func getPlayerItem() -> AVPlayerItem {
//        let temItem = AVPlayerItem(asset: self.videoOriginalAsset)
//        let timeRange = CMTimeRange(start: CMTime.zero, duration: temItem.asset.duration)
//        let videoTracks = temItem.asset.tracks(withMediaType: AVMediaType.video)
//        guard let sourceVideoTrack = videoTracks.first else {
//            return temItem
//        }
//        
//        let videoComposition = AVMutableVideoComposition(propertiesOf: temItem.asset)
//        videoComposition.customVideoCompositorClass = ZZHCustomVideoCompositor.self
//        let instruction = ZZHCustomVideoCompositionInstruction(track: sourceVideoTrack, timeRange: timeRange,  transform: sourceVideoTrack.preferredTransform, targetSize: sourceVideoTrack.naturalSize,sourceVideoURL: self.sourceVideoURL!)
//        custominstruction = instruction
//        videoComposition.instructions = [instruction]
//        temItem.videoComposition = videoComposition
//        return temItem
//    }
    
    
    func convertFrame(request:AVAsynchronousCIImageFilteringRequest){
        let compositionTime = request.compositionTime
//        let end:CMTime = CMTimeMake(value: Int64(compositionTime.value+1), timescale: compositionTime.timescale)
//        let tr = CMTimeRange(start: compositionTime, end: end)

        var ciImg:CIImage? = nil
        switch self.selectedIndex {
            case .monocular2D://双眼2d
            ciImg = request.sourceImage
            break
            
        default :
            if self.playerIsSeeking {
                quickLoadAReaderWhenSeek(startCT: compositionTime)
                ciImg = self.otherModeImgWithMode(mode: self.selectedIndex,compositionTime: compositionTime)
            }
            else {
                ciImg = self.otherModeImgWithMode(mode: self.selectedIndex,compositionTime: compositionTime)
                guard ciImg != nil else {
                    print("未合成成功.....,此处将进行重新构建assetoutput,然后再次重拾")
                    quickLoadAReaderWhenSeek(startCT: compositionTime)
                    ciImg = self.otherModeImgWithMode(mode: self.selectedIndex,compositionTime: compositionTime)
                    break
                }

            }
            break
        }
        if let ciImg {
            request.finish(with: ciImg, context: nil)
        }
        else {
            print("未合成成功.....,")
            request.finish(with: request.sourceImage, context: nil)
        }
    }
    
    func otherModeImgWithMode(mode:SpatialType,compositionTime:CMTime)->CIImage? {
        guard let ao = self.assetOutput else {
            print("assetOutput 应该是没有被创建成功.....")
            return nil
        }

        var ciImg:CIImage? = nil
//        var presentTime:CMTime? = nil
        switch mode {
        case .crossedEyes://交叉眼
            ciImg = self.videoTranserConvertor.convertVideo(asset: self.videoOriginalAsset, assetOutput: ao, type: self.selectedIndex, time: compositionTime,scale: currentScale,ed:currentED)
            break
        
        
        case .fsbs://3d全宽
            ciImg = self.videoTranserConvertor.convertVideo(asset: self.videoOriginalAsset, assetOutput: ao, type: self.selectedIndex, time: compositionTime,scale: currentScale,ed:currentED)
            break
        
        
        case .hsbs://3d半宽
            ciImg = self.videoTranserConvertor.convertVideo(asset: self.videoOriginalAsset, assetOutput: ao, type: self.selectedIndex, time: compositionTime,scale: currentScale,ed:currentED)
            break
        
        
        case .parallelEyes://平行眼
            ciImg = self.videoTranserConvertor.convertVideo(asset: self.videoOriginalAsset, assetOutput: ao, type: self.selectedIndex, time: compositionTime,scale: currentScale,ed:currentED)
            break
        
        case .redBlueSolid://红蓝立体
            ciImg = self.videoTranserConvertor.convertVideo(asset: self.videoOriginalAsset, assetOutput: ao, type: self.selectedIndex, time: compositionTime,scale: currentScale,ed:currentED)
            break
        default:
            break
        }
        //检查当前buffer的时间,如果符合反补条件,则进行反补
//        checkFBTime(ct_Buffer: presentTime)
        return ciImg
            
    }
    
    //加载assetReader和output
    func loadVideoAssetReader() async {
        do {
            if  self.assetTrack == nil {
                assetTrack = try await self.videoOriginalAsset.loadTracks(withMediaType: .video).first!
            }
                
            let timeRange = CMTimeRange(start: .zero, duration: .positiveInfinity)
            DispatchQueue.main.async {
                self.quickLoadAReader(timeRange: timeRange)
            }            
        } catch {
            print("Error loading video: \(error)")
        }
    }
    
    
    func quickLoadAReader(timeRange:CMTimeRange) {
        if(assetReader != nil){
            assetReader?.cancelReading()
        }
        do {
            assetReader = try AVAssetReader(asset: self.videoOriginalAsset)
            quickLoadAssetOutput()
            assetReader!.timeRange = timeRange
            assetReader!.add(assetOutput!)
            assetReader!.startReading()
        }
        catch {
            print("quickLoadAReader err:\(error)")
        }
        
    }
    
    //在播放器的slider 拖动播放时调用
    func quickLoadAReaderWhenSeek(startCT:CMTime) {
        print("wait thread:\(Thread.current)")
        CustomPlayerShareSemaphore.wait()
        print("wait inininin.....")
        let timeRange = CMTimeRange(start: startCT, duration: .positiveInfinity)
        self.quickLoadAReader(timeRange: timeRange)
        CustomPlayerShareSemaphore.signal()
        print("signal thread:\(Thread.current)")
    }
    
    
    
    //用于循环播放时调用,重置assetreader的timeRange
    func quickLoadAReaderWhenReplayBack()  {
//        let timeRange = CMTimeRange(start: .zero, duration: .positiveInfinity)
//        self.quickLoadAReader(timeRange: timeRange)
    }
    
    func quickLoadAssetOutput() {
        if(assetOutput != nil){
//            print("正在释放assetoutput----assetOutput:\(assetOutput) \n\(Date.now.timeIntervalSince1970)")
            assetOutput?.markConfigurationAsFinal()
//            print("正在释放assetoutput....assetOutput:\(assetOutput) \n\(Date.now.timeIntervalSince1970)")
            assetOutput = nil
//            print("释放完毕assetoutput....thread:\(Thread.current) \n\(Date.now.timeIntervalSince1970)")
        }
        
        assetOutput = AVAssetReaderTrackOutput(
            track: self.assetTrack!,
            outputSettings: [
                AVVideoDecompressionPropertiesKey: [
                    kVTDecompressionPropertyKey_RequestedMVHEVCVideoLayerIDs: [0, 1] as CFArray,
                ],
            ]
        )
//        assetOutput?.supportsRandomAccess = true
//        assetOutput?.alwaysCopiesSampleData = false
    }
}
