import Flutter
import UIKit
import AVFoundation

private let timerInterval: Double = 0.03
private let preTime: Double = 0.3
private let preLag: Double = 0.15

enum DubbingStatus {
    case stop, record, playRecord
}

public class SwiftDubbingLibPlugin: NSObject, FlutterPlugin {
    
    var registrar: FlutterPluginRegistrar!
    var channel: FlutterMethodChannel!
            
    public static func register(with registrar: FlutterPluginRegistrar) {
        let channel = FlutterMethodChannel(name: "dubbing_lib", binaryMessenger: registrar.messenger())
        let instance = SwiftDubbingLibPlugin()
        registrar.addMethodCallDelegate(instance, channel: channel)
        instance.channel = channel
        instance.registrar = registrar
    }
    
    public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
        let args = call.arguments as? [String: Any];
        switch call.method {
        case "getPlatformVersion":
            result("iOS " + UIDevice.current.systemVersion)
            break
        case "mixinVideoAndAudio":
            let videoPath = args!["videoPath"] as! String;
            let bgmPath = args!["bgmPath"] as! String;
            let resultPath = args!["resultPath"] as! String;
            
            mixinVideo(bgmPath: bgmPath, videoPath: videoPath, outPath: resultPath, result: result)
            break
        case "mixinAudio":
            let bgmPath = args!["bgmPath"] as! String;
            let audioPathList = args!["audioPaths"] as! [String];
            let startTimeList = args!["startTimeList"] as! [Double];
            let pathVideoMixinDir = args!["resultPath"] as! String;
            mixinAudio(bgmPath: bgmPath, audioPathList: audioPathList, startTimeList: startTimeList, outPath: pathVideoMixinDir, result: result)
            break;
        case "setExtraFullScreen":
            result("")
            break
        default:
            result(FlutterMethodNotImplemented)
        }
    }
    
    /// 合成音频
    func mixinAudio(bgmPath: String, audioPathList: [String], startTimeList: [Double], outPath: String, result: @escaping FlutterResult) {
        let musicUrl = URL(fileURLWithPath: bgmPath)
        let composer = DubbingComposer(timeline: startTimeList, musicUrl: musicUrl, recordsUrl: audioPathList)
        
        composer.preTime = preLag
        let outputUrl = URL(fileURLWithPath: outPath)
        DispatchQueue.global().async {
            composer.compose(outputUrl, onSuccess: {
                result(outPath)
            }) { (message) in
                print("合成失败", message)
                result(FlutterError(code: "1005", message: "mix audio failed", details: nil))
            }
        }
    }
    
    /// 合成视频
    func mixinVideo(bgmPath: String, videoPath: String, outPath: String, result: @escaping FlutterResult) {
        let musicUrl = URL(fileURLWithPath: bgmPath)
        let videoUrl = URL(fileURLWithPath: videoPath)

        let composer = VideoComposer(videoUrl: videoUrl, musicUrl: musicUrl)
        
        let outputUrl = URL(fileURLWithPath: outPath)
        DispatchQueue.global().async {
            composer.compose(outputUrl, onSuccess: {
                result(outPath)
            }) { (message) in
                print("合成失败", message)
                result(FlutterError(code: "1006", message: "mix video failed", details: nil))
            }
        }
    }
}

extension String{
    /// check string cellection is whiteSpace
    var isBlank : Bool{
        return allSatisfy({$0.isWhitespace})
    }
}


extension Optional where Wrapped == String{
    var isBlank : Bool{
        return self?.isBlank ?? true
    }
}
