//
//  SpeakVideoPlayer.swift
//  SpeakEasyLearnEnglish
//
//  Created by edy on 2025/7/7.
//

import UIKit
import AVFoundation

class SpeakVideoPlayer {
    
    enum videoState {
        case runloop
        case full
        case none
    }
    
    var SpeakPlayer:AVPlayer?
    var SpeakPlayerLayer:AVPlayerLayer?
    private var playerItem:AVPlayerItem?
    private var SpeakPlayCount:Int = 0
    private var SpeakCurrentPlay:Int = 0
    var duration:Double = 1
    var PlayFinish:(()->Void)?
    
    private var rate = 1.0;
    
    open func videoPlayer(_ rate:Double = 1 , playCount:Int = 0) -> Void {
        SpeakPlayCount = playCount
        self.play()
        self.rate = rate
        DispatchQueue.main.asyncAfter(deadline: .now()+0.01) {
            self.SpeakCurrentPlay = 0
            self.SpeakPlayer?.rate = Float(rate)
        }
    }
    
    init() { }
    
    func loadVideo( state:videoState ,_ idx:Int? = nil) -> Void {
        var index = idx ?? 0
        if idx == nil {
            index = SpeakElePublicManager.share.PublicData.AIerIndex
        }
        let name = (SpeakHomeViewModel().AIser()[safe:index]?.name ?? "") + (state == .none ? "M" : "")
        if let path = Bundle.main.path(forResource: name, ofType: ".mp4") {
            let url = URL(fileURLWithPath: path)
            self.setupPlayers(videoURL: url)
        }
    }
    
    private func setupPlayers(videoURL: URL) {
        let asset = AVAsset(url: videoURL)
        playerItem = AVPlayerItem(asset: asset)
        playerItem?.audioTimePitchAlgorithm = .spectral
        
        let player = AVPlayer(playerItem: playerItem)
        self.SpeakPlayer = player
        let playerLayer = AVPlayerLayer(player: self.SpeakPlayer)
        playerLayer.videoGravity = .resizeAspectFill
        playerLayer.shouldRasterize = true
        playerLayer.rasterizationScale = UIScreen.main.nativeScale
        self.SpeakPlayerLayer = playerLayer
        asset.loadValuesAsynchronously(forKeys: ["duration"]) { [weak self] in
            DispatchQueue.main.async {
                var error: NSError?
                let status = asset.statusOfValue(forKey: "duration", error: &error)
                switch status {
                case .loaded:
                    let duration = asset.duration.seconds
                    self?.duration = duration
                    break
                default:
                    break
                }
            }
        }
        NotificationCenter.default.addObserver(
            forName: .AVPlayerItemDidPlayToEndTime,
            object: playerItem,
            queue: .main
        ) { [weak player] _ in
            if self.SpeakPlayCount > 0 {
                self.SpeakCurrentPlay += 1
                Print(self.SpeakCurrentPlay)
                if self.SpeakCurrentPlay >= self.SpeakPlayCount {
                    player?.seek(to: .zero)
                    if let call = self.PlayFinish {
                        call()
                    }
                    return
                }
                player?.seek(to: .zero)
                player?.play()
                DispatchQueue.main.asyncAfter(deadline: .now()+0.01, execute: {
                    player?.rate = Float(self.rate)
                })
            }else{
                player?.seek(to: .zero)
                player?.play()
                DispatchQueue.main.asyncAfter(deadline: .now()+0.01, execute: {
                    player?.rate = Float(self.rate)
                })
            }
        }
    }
    
    func play() {
        SpeakPlayer?.play()
    }
    
    func pause() {
        SpeakPlayer?.pause()
    }
    
    func stop() -> Void {
        SpeakPlayer?.pause()
        SpeakPlayer?.seek(to: .zero)
    }
    
    deinit {
        SpeakPlayer?.pause()
        NotificationCenter.default.removeObserver(self)
    }
    
}
