//
//  YHPlayerManager.swift
//  galaxy
//
//  Created by alexzzw on 2024/11/29.
//  Copyright © 2024 https://www.galaxy-immi.com. All rights reserved.
//

import AgoraRtcKit
import UIKit

// MARK: - 播放器管理中心

class YHPlayerManager: NSObject {
    // MARK: - Types

    enum PlaybackScene: Int {
        case fullscreen
        case floating
        case banner
    }

    struct PlaybackInfo: Equatable {
        let id: Int
        var url: String?
        var title: String?
        var roomId: String?
        var token: String?
        var channelId: String?
        var uid: UInt?
        let isLive: Bool
        var scene: PlaybackScene
        var playerType: YHPlayerType
        var isFromSaleDetail: Bool = false

        init(id: Int,
             url: String? = nil,
             title: String? = nil,
             roomId: String? = nil,
             token: String? = nil,
             channelId: String? = nil,
             uid: UInt? = nil,
             isLive: Bool,
             scene: PlaybackScene = .fullscreen,
             playerType: YHPlayerType = .main,
             isFromSaleDetail: Bool = false) {
            self.id = id
            self.url = url
            self.title = title
            self.roomId = roomId
            self.token = token
            self.channelId = channelId
            self.uid = uid
            self.isLive = isLive
            self.scene = scene
            self.playerType = playerType
            self.isFromSaleDetail = isFromSaleDetail
        }

        static func == (lhs: Self, rhs: Self) -> Bool {
            lhs.id == rhs.id && lhs.isLive == rhs.isLive
        }
    }

    // MARK: - Properties

    static let shared = YHPlayerManager()

    var agoraKit: AgoraRtcEngineKit!
    private var mainChannelDelegate: YHMainChannelDelegate?
    private var secondaryChannelDelegate: YHSecondaryChannelDelegate?
    private var activePlayers: [YHPlayerType: YHPlayer] = [:]
    private var currentPlaybackInfo: [YHPlayerType: PlaybackInfo] = [:]
    private(set) var floatingWindow: YHFloatingWindow?
    private(set) var isInRecommendPage: Bool = false
    private(set) var isConfigFloating: Bool? = nil
    private var bannerAutoPlayEnabled: Bool = true
    private var bannerPlayerView: UIView?

    private var transitionSourceView: UIView?

    // MARK: - Initialization

    override private init() {
        super.init()
        setupChannelDelegates()
        setupAgoraKit()
    }
    
    private func setupChannelDelegates() {
        mainChannelDelegate = YHMainChannelDelegate()
        secondaryChannelDelegate = YHSecondaryChannelDelegate()
    }

    private func setupAgoraKit() {
        let config = AgoraRtcEngineConfig()
        config.appId = YhConstant.AgoraRtcKit.appId
        config.channelProfile = .liveBroadcasting
        agoraKit = AgoraRtcEngineKit.sharedEngine(with: config, delegate: mainChannelDelegate)
        // Enable video
        agoraKit.enableVideo()
        // Set client role as audience
        let options = AgoraClientRoleOptions()
        options.audienceLatencyLevel = .lowLatency
        agoraKit.setClientRole(.audience, options: options)
        // Set audio route to speaker
        agoraKit.setDefaultAudioRouteToSpeakerphone(true)
    }

    // MARK: - Basic Playback Control

    func play(url: String, inView view: UIView? = nil, title: String? = nil, type: YHPlayerType = .main, isLive: Bool = false) {
        let player = player(for: type)
        player.play(url: url, title: title, view: view, isLive: isLive)
    }

    func pause(type: YHPlayerType = .main) {
        activePlayers[type]?.pause()
    }

    func resume(type: YHPlayerType = .main) {
        activePlayers[type]?.resume()
    }

    func stop(type: YHPlayerType = .main) {
        activePlayers[type]?.stop()
    }

    func getCurrentPlayer(type: YHPlayerType = .main) -> YHPlayer? {
        return activePlayers[type]
    }

    func setMute(_ muted: Bool, type: YHPlayerType = .main) {
        activePlayers[type]?.isMuted = muted
    }

    func getPlayer(_ type: YHPlayerType) -> YHPlayer? {
        return activePlayers[type]
    }

    // MARK: - Resource Management

    func cleanupOnExit() {
        // 停止所有播放
        activePlayers.forEach { $0.value.stop() }

        // 释放副播放器
        //releasePlayer(.secondary)

        // 清理播放信息
        currentPlaybackInfo.removeAll()
        floatingWindow?.dismiss()
        clearFloatingWindow()

        // 重置主播放器
        if let mainPlayer = activePlayers[.main] {
            mainPlayer.reset()
        }
    }
    
    private func clearFloatingWindow() {
        floatingWindow = nil
        if isInRecommendPage {
            enableBannerAutoPlay()
        }
    }

    deinit {
        activePlayers.forEach { $0.value.releasePlayer() }
        activePlayers.removeAll()
        AgoraRtcEngineKit.destroy()
    }

    // MARK: - Player Management

    private func player(for type: YHPlayerType) -> YHPlayer {
        if let existingPlayer = activePlayers[type] {
            return existingPlayer
        }

        let newPlayer = createPlayer(for: type)
        activePlayers[type] = newPlayer
        return newPlayer
    }

    private func createPlayer(for type: YHPlayerType) -> YHPlayer {
        let playerKit = agoraKit.createMediaPlayer(with: self)
        let player = YHPlayer(type: type, playerKit: playerKit, agoraKit: agoraKit)
        // 设置对应的 delegate
        if type == .main {
            mainChannelDelegate?.player = player
        } else {
            secondaryChannelDelegate?.player = player
        }
        return player
    }

    private func releasePlayer(_ type: YHPlayerType) {
        guard let player = activePlayers[type] else { return }
        player.stop()
        player.releasePlayer()
        activePlayers.removeValue(forKey: type)
        currentPlaybackInfo.removeValue(forKey: type)
    }

    private func determinePlayerType(for scene: PlaybackScene) -> YHPlayerType {
        switch scene {
        case .banner:
            return .secondary
        case .fullscreen, .floating:
            return .main
        }
    }
    
    private func checkLogin() -> Bool {
        if YHLoginManager.shared.isLogin() == false {
            YHOneKeyLoginManager.shared.oneKeyLogin()
            return false
        }
        return true
    }
    
    // 加入频道的逻辑移到 PlayerManager
    func joinChannel(for player: YHPlayer,
                           token: String,
                           channelId: String,
                     uid: UInt, view: UIView?, defaultMuted: Bool = false) {
        let option = AgoraRtcChannelMediaOptions()
        option.publishCameraTrack = false
        option.publishMicrophoneTrack = false
        option.autoSubscribeVideo = true
        option.autoSubscribeAudio = true
        option.clientRoleType = .audience
        player.setPlayModeAndPlayView(.live, view)
        if player.type == .secondary {
            let connection = AgoraRtcConnection()
            connection.channelId = channelId
            connection.localUid = uid
            
            secondaryChannelDelegate?.channelId = channelId
            
            let result = agoraKit.joinChannelEx(byToken: token,
                                              connection: connection,
                                              delegate: secondaryChannelDelegate,
                                                mediaOptions: option) { [weak self] _, _, _ in
                if defaultMuted {
                    self?.agoraKit.disableAudio()
                } else {
                    self?.agoraKit.enableAudio()
                }
            }
            if result == 0 {
                player.setJoinInfo(token: token, channelId: channelId, uid: uid)
            } else {
                //-2: #AgoraErrorCodeInvalidArgument
                //-3: #AgoraErrorCodeNotReady
                //-5: #AgoraErrorCodeRefused
                var errorMsg = "加入失败"
                switch result {
                case -2:
                    errorMsg = "AgoraErrorCodeInvalidArgument"
                case -3:
                    errorMsg = "AgoraErrorCodeNotReady"
                case -5:
                    errorMsg = "AgoraErrorCodeRefused"
                default:
                    break
                }
                let dic: [AnyHashable : Any] = [
                    "type": "joinLiveChannelError",
                    "channelId" : channelId,
                    "uid" : uid,
                    "errorMsg": errorMsg
                ]
                YHAliYunLogManager.shared.addModuleName(.logTypeError, remark: dic)
            }
        } else {
            mainChannelDelegate?.channelId = channelId
            if defaultMuted {
                agoraKit.disableAudio()
            } else {
                agoraKit.enableAudio()
            }
            let result = agoraKit.joinChannel(byToken: token,
                                           channelId: channelId,
                                           uid: uid,
                                           mediaOptions: option,
                                           joinSuccess: nil)
            if result == 0 {
                player.setJoinInfo(token: token, channelId: channelId, uid: uid)
            } else {
                //-2: #AgoraErrorCodeInvalidArgument
                //-3: #AgoraErrorCodeNotReady
                //-5: #AgoraErrorCodeRefused
                var errorMsg = "加入失败"
                switch result {
                case -2:
                    errorMsg = "AgoraErrorCodeInvalidArgument"
                case -3:
                    errorMsg = "AgoraErrorCodeNotReady"
                case -5:
                    errorMsg = "AgoraErrorCodeRefused"
                default:
                    break
                }
                let dic: [AnyHashable : Any] = [
                    "type": "joinLiveChannelError",
                    "channelId" : channelId,
                    "uid" : uid,
                    "errorMsg": errorMsg
                ]
                YHAliYunLogManager.shared.addModuleName(.logTypeError, remark: dic)
            }
        }
    }
    
    func leaveChannel(for player: YHPlayer) {
        guard let channelId = player.currentChannelId,
              let uid = player.currentUid else { return }
        
        if player.type == .secondary {
            let connection = AgoraRtcConnection()
            connection.channelId = channelId
            connection.localUid = uid
            //agoraKit.disableVideo()
            //agoraKit.disableAudio()
            agoraKit.leaveChannelEx(connection)
            //AgoraRtcEngineKit.destroy()
        } else {
            //agoraKit.disableVideo()
            //agoraKit.disableAudio()
            agoraKit.leaveChannel(nil)
            //AgoraRtcEngineKit.destroy()
        }
        
        player.clearJoinInfo()
    }

    // MARK: - Scene Management

    func enterVOD(from sourceView: UIView?, playbackInfo: PlaybackInfo) {
        NotificationCenter.default.post(name: YhConstant.YhNotification.closeShareUIInLiveRoomNotifiction, object: nil)
        let playerType = determinePlayerType(for: .fullscreen)
        var updatedInfo = playbackInfo
        updatedInfo.scene = .fullscreen
        updatedInfo.playerType = playerType

        // 如果是从banner跳转，需要转移播放进度
        var startPosition: Int = 0
//        if let bannerPlayer = activePlayers[.secondary] {
//            startPosition = bannerPlayer.getPosition()
//            if bannerPlayer.playMode == .live {
//                leaveChannel(for: bannerPlayer)
//            } else {
//                bannerPlayer.pause()
//            }
//        }
        var lastVodVC: YHVODPlayerViewController?
        var lastNav: UINavigationController?
        var lastLiveVC: YHLivePlayerViewController?
        if let topVC = UIApplication.shared.yhKeyWindow()?.rootViewController?.topMostViewController(), let nav = topVC.navigationController {
            let viewControllers = nav.viewControllers
            lastVodVC = viewControllers.last { vc in
                vc is YHVODPlayerViewController
            } as? YHVODPlayerViewController
            lastLiveVC = viewControllers.last { vc in
                vc is YHLivePlayerViewController
            } as? YHLivePlayerViewController
            lastNav = nav
        }

        let playerVC = YHVODPlayerViewController(id: playbackInfo.id, url: playbackInfo.url, title: playbackInfo.title)
        let navVC = YHNavigationController(rootViewController: playerVC)
        currentPlaybackInfo[playerType] = updatedInfo

        let player = player(for: playerType)
        player.delegate = playerVC
        playerVC.player = player
        playerVC.playbackInfo = updatedInfo
        playerVC.startPosition = startPosition

        // 关闭小窗
        var needExitFloating = false
        if floatingWindow != nil {
            if sourceView != floatingWindow?.contentView {
                needExitFloating = false
                exitFloating()
            } else {
                needExitFloating = true
            }
        }

        if let url = playbackInfo.url {
            player.play(url: url, title: playbackInfo.title, view: playerVC.playerView)
        }
        if let lastNav = lastNav, lastVodVC != nil {
            lastNav.viewControllers.removeAll()
            var viewControllers = lastNav.viewControllers
            viewControllers.append(playerVC)
            lastNav.setViewControllers(viewControllers, animated: true)
        } else if let lastNav = lastNav, lastLiveVC != nil {
            lastNav.pushViewController(playerVC, animated: true)
        } else {
            present(navVC, from: sourceView)
        }
        
        if needExitFloating, floatingWindow != nil {
            floatingWindow?.dismiss()
            clearFloatingWindow()
        }
    }

    func enterLive(from sourceView: UIView?, playbackInfo: PlaybackInfo) {
        
        NotificationCenter.default.post(name: YhConstant.YhNotification.closeShareUIInLiveRoomNotifiction, object: nil)
        
        let playerType = determinePlayerType(for: .fullscreen)
        var updatedInfo = playbackInfo
        updatedInfo.scene = .fullscreen
        updatedInfo.playerType = playerType

        // 如果是从banner跳转，需要转移播放进度
//        if let bannerPlayer = activePlayers[.secondary] {
//            if bannerPlayer.playMode == .live {
//                leaveChannel(for: bannerPlayer)
//            } else {
//                bannerPlayer.pause()
//            }
//        }
        var lastVodVC: YHVODPlayerViewController?
        var lastNav: UINavigationController?
        var lastLiveVC: YHLivePlayerViewController?
        if let topVC = UIApplication.shared.yhKeyWindow()?.rootViewController?.topMostViewController(), let nav = topVC.navigationController {
            let viewControllers = nav.viewControllers
            lastVodVC = viewControllers.last { vc in
                vc is YHVODPlayerViewController
            } as? YHVODPlayerViewController
            lastLiveVC = viewControllers.last { vc in
                vc is YHLivePlayerViewController
            } as? YHLivePlayerViewController
            lastNav = nav
        }

        let playerVC = YHLivePlayerViewController(id: playbackInfo.id,
                                                  url: nil,
                                                  title: playbackInfo.title,
                                                  roomId: playbackInfo.roomId)
        let navVC = YHNavigationController(rootViewController: playerVC)
        currentPlaybackInfo[playerType] = updatedInfo

        let player = player(for: playerType)
        player.delegate = playerVC
        playerVC.player = player
        playerVC.playbackInfo = updatedInfo

        // 关闭小窗
        var needExitFloating = false
        if floatingWindow != nil {
            if sourceView != floatingWindow?.contentView {
                needExitFloating = false
                exitFloating()
            } else {
                needExitFloating = true
            }
        }

        /*
        // 加入频道
        if let token = playbackInfo.token,
           let channelId = playbackInfo.channelId, let uid = playbackInfo.uid, !token.isEmpty, !channelId.isEmpty {
            if player.isJoined {
                leaveChannel(for: player)
                joinChannel(for: player, token: token, channelId: channelId, uid: uid, view: playerVC.playerView)
//                // 先清理上次的播放状态
//                player.clearPlayerView()
//                // 将播放状态转移到floating
//                player.setPlayModeAndPlayView(.live, playerVC.playerView)
            } else {
                joinChannel(for: player, token: token, channelId: channelId, uid: uid, view: playerVC.playerView)
            }
        }
         */
        leaveChannel(for: player)

        if let lastNav = lastNav, lastLiveVC != nil {
            lastNav.viewControllers.removeAll()
            var viewControllers = lastNav.viewControllers
            viewControllers.append(playerVC)
            lastNav.setViewControllers(viewControllers, animated: true)
        } else if let lastNav = lastNav, lastVodVC != nil {
            lastNav.pushViewController(playerVC, animated: true)
        } else {
            present(navVC, from: sourceView)
        }
        if needExitFloating, floatingWindow != nil {
            floatingWindow?.dismiss()
            clearFloatingWindow()
        }
    }

    func enterFloating(from viewController: UIViewController? = nil, playbackInfo: PlaybackInfo, isConfigured: Bool = false) {
        if isConfigured {
            self.isConfigFloating = isConfigured
        }
        guard let window = UIApplication.shared.yhKeyWindow() else { return }
        guard floatingWindow == nil else {
            return
        }
        
        let isCurrentFromLive = viewController is YHLivePlayerViewController
        let isCurrentFromVod = viewController is YHVODPlayerViewController
        // 如果是配置产生的小窗，但不在推荐页，则不创建
        if isConfigured && !isInRecommendPage {
            return
        }
                
        if !isCurrentFromLive, !isCurrentFromVod, let topVC = UIApplication.shared.yhKeyWindow()?.rootViewController?.topMostViewController() {
            // 如果当前顶部控制器是播放器页面，则不创建浮窗
            if topVC is YHLivePlayerViewController || topVC is YHVODPlayerViewController {
                return
            }
        }
        
        // 如果是从banner跳转，需要转移播放进度
//        if let bannerPlayer = activePlayers[.secondary] {
//            if bannerPlayer.playMode == .live {
//                leaveChannel(for: bannerPlayer)
//            } else {
//                bannerPlayer.pause()
//            }
//        }
        
        let playerType = determinePlayerType(for: .floating)
        let player: YHPlayer = player(for: playerType)
        var needMuteLive: Bool = false
        if isConfigured {
            if playbackInfo.isLive {
                needMuteLive = true
            } else {
                player.isMuted = true
            }
        } else {
            if playbackInfo.isLive {
                needMuteLive = false
            } else {
                player.isMuted = false
            }
        }

        var updatedInfo = playbackInfo
        updatedInfo.scene = .floating
        updatedInfo.playerType = playerType
        currentPlaybackInfo[playerType] = updatedInfo

        // 获取当前播放视图的截图和位置
        if let sourceView = player.currentPlayView,
           let sourceSuperview = sourceView.superview {
            let sourceFrame = sourceSuperview.convert(sourceView.frame, to: window)
            let snapshotView = sourceView.snapshotView(afterScreenUpdates: false) ?? UIView()
            snapshotView.frame = sourceFrame

            // 创建浮窗
            let floatingWindow = YHFloatingWindow()
            floatingWindow.playbackInfo = updatedInfo
            floatingWindow.delegate = self
            floatingWindow.player = player
            player.delegate = floatingWindow
            floatingWindow.source = isConfigured ? .configured : .userAction
            self.floatingWindow = floatingWindow

            // 添加截图视图到窗口
            window.addSubview(snapshotView)

            // 计算目标位置
            let targetFrame = floatingWindow.calculateInitialFrame()
            // 检查是否存在当前播放器
            // 加入频道
            if let token = playbackInfo.token,
               let channelId = playbackInfo.channelId,
               let uid = playbackInfo.uid, !token.isEmpty, !channelId.isEmpty {
                if player.isJoined {
                    leaveChannel(for: player)
                    joinChannel(for: player, token: token, channelId: channelId, uid: uid, view: floatingWindow.contentView, defaultMuted: needMuteLive)
//                    // 先清理上次的播放状态
//                    player.clearPlayerView()
//                    // 将播放状态转移到floating
//                    player.setPlayModeAndPlayView(.live, floatingWindow.contentView)
                    
                } else {
                    joinChannel(for: player, token: token, channelId: channelId, uid: uid, view: floatingWindow.contentView)
                }
            } else if let url = playbackInfo.url, !url.isEmpty {
                player.play(url: url, title: playbackInfo.title, view: floatingWindow.contentView)
            }

            // 执行动画
            let showFloatingWindow = {
                UIView.animate(withDuration: 0.3, animations: {
                    snapshotView.frame = targetFrame
                }, completion: { _ in
                    snapshotView.removeFromSuperview()
                    floatingWindow.show(in: window)
                    //player.setPlayView(floatingWindow.contentView)
                })
            }

            if let viewController = viewController {
                showFloatingWindow()
                viewController.dismiss(animated: false)
            } else {
                showFloatingWindow()
            }
        } else {
            // 直接创建浮窗
            let floatingWindow = YHFloatingWindow()
            floatingWindow.delegate = self
            floatingWindow.player = player
            floatingWindow.playbackInfo = updatedInfo
            floatingWindow.source = isConfigured ? .configured : .userAction
            self.floatingWindow = floatingWindow
            player.delegate = floatingWindow
            // 检查是否存在当前播放器
            if let token = playbackInfo.token,
               let channelId = playbackInfo.channelId,
               let uid = playbackInfo.uid, !token.isEmpty, !channelId.isEmpty {
                leaveChannel(for: player)
                joinChannel(for: player, token: token, channelId: channelId, uid: uid, view: floatingWindow.contentView, defaultMuted: needMuteLive)
            } else if let url = playbackInfo.url, !url.isEmpty {
                player.play(url: url, title: playbackInfo.title, view: floatingWindow.contentView)
            }

            let showFloatingWindow = {
                floatingWindow.show(in: window)
            }

            if let viewController = viewController {
                viewController.dismiss(animated: true) {
                    showFloatingWindow()
                }
            } else {
                showFloatingWindow()
            }
        }
    }

    func enterBanner(playbackInfo: PlaybackInfo, inView view: UIView) {
        // 检查是否应该播放banner
        if !shouldPlayBanner() {
            return
        }
        let playerType = determinePlayerType(for: .banner)
        var updatedInfo = playbackInfo
        updatedInfo.scene = .banner
        updatedInfo.playerType = playerType
        currentPlaybackInfo[playerType] = updatedInfo
        bannerPlayerView = view
        let player = player(for: playerType)
        if playbackInfo.isLive {
            // 加入频道
            if let token = playbackInfo.token,
               let channelId = playbackInfo.channelId, let uid = playbackInfo.uid, !token.isEmpty, !channelId.isEmpty {
                if player.isJoined {
                    leaveChannel(for: player)
                    joinChannel(for: player, token: token, channelId: channelId, uid: uid, view: view, defaultMuted: true)
                } else {
                    joinChannel(for: player, token: token, channelId: channelId, uid: uid, view: view, defaultMuted: true)
                }
            }
        } else {
            if let url = playbackInfo.url, !url.isEmpty {
               player.play(url: url, title: playbackInfo.title, view: view)
           }
        }
    }

    func exitFloating() {
        guard let floatingWindow = floatingWindow else {
            return
        }
        // 直播退出channel
        if floatingWindow.playbackInfo?.isLive == true, let player = floatingWindow.player {
            leaveChannel(for: player)
        } else {
            floatingWindow.player?.stop()
        }
        floatingWindow.dismiss()
        clearFloatingWindow()
    }

    private func present(_ playerVC: UIViewController, from sourceView: UIView?) {
        playerVC.modalPresentationStyle = .fullScreen
        playerVC.transitioningDelegate = self
        transitionSourceView = sourceView

        if let topVC = UIApplication.shared.yhKeyWindow()?.rootViewController?.topMostViewController() {
            topVC.present(playerVC, animated: true) { [weak self] in
                self?.transitionSourceView = nil
            }
        }
    }
}

// MARK: - AgoraRtcMediaPlayerDelegate

extension YHPlayerManager: AgoraRtcMediaPlayerDelegate {
    func AgoraRtcMediaPlayer(_ playerKit: AgoraRtcMediaPlayerProtocol,
                             didChangedTo state: AgoraMediaPlayerState,
                             reason: AgoraMediaPlayerReason) {
        if let player = activePlayers.values.first(where: { $0.playerKit === playerKit }) {
            player.delegate?.player(player, didChangedToState: state, reason: reason)
        }
    }

    func AgoraRtcMediaPlayer(_ playerKit: AgoraRtcMediaPlayerProtocol,
                             didChangedTo position: Int) {
        if let player = activePlayers.values.first(where: { $0.playerKit === playerKit }) {
            player.delegate?.player(player, didChangedToPosition: position)
        }
    }
    
    func AgoraRtcMediaPlayer(_ playerKit: any AgoraRtcMediaPlayerProtocol, didChangedTo positionMs: Int, atTimestamp timestampMs: TimeInterval) {
        if let player = activePlayers.values.first(where: { $0.playerKit === playerKit }) {
            player.delegate?.player(player, didChangedTo: positionMs, atTimestamp: timestampMs)
        }
    }

    func AgoraRtcMediaPlayer(_ playerKit: AgoraRtcMediaPlayerProtocol,
                             infoUpdated info: AgoraMediaPlayerUpdatedInfo) {
        // 获取视频尺寸信息
        let videoWidth = info.videoWidth
        let videoHeight = info.videoHeight
        let videoSize = CGSize(width: CGFloat(videoWidth), height: CGFloat(videoHeight))

        if let player = activePlayers.values.first(where: { $0.playerKit === playerKit }) {
            player.delegate?.player(player, didReceiveVideoSize: videoSize)
        }

        if floatingWindow?.player?.playerKit === playerKit {
            DispatchQueue.main.async {
                self.floatingWindow?.setVideoSize(videoSize)
            }
        }
    }
}

// MARK: - YHFloatingWindowDelegate

extension YHPlayerManager: YHFloatingWindowDelegate {
    private func findPlayerType(for playbackInfo: PlaybackInfo) -> YHPlayerType? {
        return currentPlaybackInfo.first(where: { $0.value == playbackInfo })?.key
    }

    func floatingWindowDidTap(_ window: YHFloatingWindow) {
        guard let playbackInfo = window.playbackInfo else { return }
        guard checkLogin() else { return }
        if window.source == .configured {
            YHAnalytics.track("APP_Home_LiveWindow")
        }
        if playbackInfo.isLive {
            enterLive(from: window.contentView, playbackInfo: playbackInfo)
        } else {
            enterVOD(from: window.contentView, playbackInfo: playbackInfo)
        }
    }

    func floatingWindowDidClose(_ window: YHFloatingWindow) {
        guard let playbackInfo = window.playbackInfo,
              let playerType = findPlayerType(for: playbackInfo) else {
            return
        }

        let player = player(for: playerType)
        clearFloatingWindow()
        leaveChannel(for: player)
        if window.source == .configured {
            isConfigFloating = false
        }
    }

    func floatingWindow(_ window: YHFloatingWindow, didChangeSize size: CGSize) {
        // 处理浮窗大小变化
    }

    func floatingWindow(_ window: YHFloatingWindow, didChangePosition point: CGPoint) {
        // 处理浮窗位置变化
    }
}

// MARK: - UIViewControllerTransitioningDelegate

extension YHPlayerManager: UIViewControllerTransitioningDelegate {
    func animationController(forPresented presented: UIViewController,
                             presenting: UIViewController,
                             source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        if let sourceView = transitionSourceView {
            return YHPlayerTransitionAnimator(type: .zoomIn, sourceView: sourceView)
        } else {
            return YHPlayerTransitionAnimator(type: .push)
        }
    }

    func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        if let sourceView = transitionSourceView {
            return YHPlayerTransitionAnimator(type: .zoomOut, sourceView: sourceView)
        } else {
            return YHPlayerTransitionAnimator(type: .pop)
        }
    }
}

// MARK: - UIViewController Extension

extension UIViewController {
    func topMostViewController() -> UIViewController {
        if let presented = presentedViewController {
            return presented.topMostViewController()
        }

        if let navigation = self as? UINavigationController {
            return navigation.visibleViewController?.topMostViewController() ?? navigation
        }

        if let tab = self as? UITabBarController {
            return tab.selectedViewController?.topMostViewController() ?? tab
        }

        return self
    }
}

extension YHPlayerManager {
    // MARK: - Page Management
    func handlePageChanged(isRecommendPage: Bool) {
        self.isInRecommendPage = isRecommendPage
        if isRecommendPage {
            if isConfigFloating == true {
                if let window = floatingWindow, let player = window.player, window.source == .configured {
                    //stopBannerPlayback()
                    resumeConfiguredFloatingWindow(window, player)
                }
            } else {
                if let window = floatingWindow, window.source == .configured {
                    exitFloating()
                }
                //enableBannerAutoPlay()
            }
        } else {
            if let window = floatingWindow, window.source == .configured {
                exitFloating()
            }
            //stopBannerPlayback()
        }
    }
    
    private func resumeConfiguredFloatingWindow(_ window: YHFloatingWindow, _ player: YHPlayer) {
        if let playbackInfo = window.playbackInfo {
            if playbackInfo.isLive {
                if let token = playbackInfo.token,
                   let channelId = playbackInfo.channelId,
                   let uid = playbackInfo.uid {
                    joinChannel(for: player,
                              token: token,
                              channelId: channelId,
                              uid: uid,
                              view: window.contentView)
                }
            } else {
                if let url = playbackInfo.url {
                    player.play(url: url,
                              title: playbackInfo.title,
                              view: window.contentView)
                }
            }
        }
    }
    
    private func stopConfiguredFloatingWindow(_ window: YHFloatingWindow, _ player: YHPlayer) {
        if player.playMode == .live {
            leaveChannel(for: player)
        } else {
            player.stop()
        }
    }
    
//    private func stopBannerPlayback() {
//        bannerAutoPlayEnabled = false
//        if let player = getPlayer(.secondary) {
//            if player.playMode == .live {
//                leaveChannel(for: player)
//            } else {
//                player.stop()
//            }
//        }
//    }
    
//    private func resumeBannerPlayback() {
//        guard bannerAutoPlayEnabled, let bannerPlayerView = bannerPlayerView else {
//            return
//        }
//        if let player = getPlayer(.secondary) {
//            if let playbackInfo = currentPlaybackInfo[.secondary] {
//                if playbackInfo.isLive {
//                    if let token = playbackInfo.token,
//                       let channelId = playbackInfo.channelId,
//                       let uid = playbackInfo.uid {
//                        joinChannel(for: player,
//                                  token: token,
//                                  channelId: channelId,
//                                  uid: uid,
//                                    view: bannerPlayerView, defaultMuted: true)
//                    }
//                } else {
//                    if let url = playbackInfo.url {
//                        player.play(url: url,
//                                  title: playbackInfo.title,
//                                  view: bannerPlayerView)
//                        player.isMuted = true
//                    }
//                }
//            }
//            
//        }
//    }
    
    private func enableBannerAutoPlay() {
        bannerAutoPlayEnabled = true
    }
    
    func shouldPlayBanner() -> Bool {
        if floatingWindow != nil {
            return false
        }
        return bannerAutoPlayEnabled
    }
}
