//
//  PlayDetailViewController.swift
//  ColorfulWallpaper
//
//  Created by nkl on 2024/9/13.
//

// import ADManager
import Combine
import Foundation
import KLTips
import MediaPlayer
import SJVideoPlayer
import TSVideoKit
import UIKit

class PlayDetailViewController: LWBGViewController {
    var playControl: TSVideoPlayController {
        if !(TSVideoOperator.shared.playerController.player.playbackController is SJIJKMediaPlaybackController) {
            TSVideoOperator.shared.playerController.player.playbackController = SJIJKMediaPlaybackController()
            TSVideoOperator.shared.playerController.player.isPausedInBackground = false
            TSVideoOperator.shared.playerController.player.rotationManager?.isDisabledAutorotation = true
            TSVideoOperator.shared.playerController.player.delayInSecondsForHiddenPlaceholderImageView = 0
        }
        return TSVideoOperator.shared.playerController
    }

    lazy var customLoading: SJLoadingView = SJLoadingView()

    lazy var placeHolderView: PlayDetailPlaceHolderView = PlayDetailPlaceHolderView()

    lazy var retryButton: UIButton = {
        let btn = UIButton()
        btn.setTitle("Reload", for: .normal)
        btn.setTitleColor(.white, for: .normal)
        btn.titleLabel?.font = .systemFont(ofSize: 14)
        btn.customCornerRadius = 20
        btn.isHidden = true
        return btn
    }()

    lazy var topView: PlayDetailTopView = PlayDetailTopView()
    lazy var controlView: PlayDetailControlView = PlayDetailControlView()
    var downloader: NewChunkDownloader?
    private var timer: Timer?
    private var cancellable: [AnyCancellable] = []
    private var downloaderCancellable: [AnyCancellable] = []

    override func viewDidLoad() {
        super.viewDidLoad()
        bgImageView.image = .viewMainBg
        playControl.view.backgroundColor = .clear

        addNotifaction()
        addActionTargets()
    }

    func updateNavibar(video: TSVideo?) {
        if video?.videoStatus == .cached {
            topView.moreButton.isHidden = false
        } else {
            topView.moreButton.isHidden = true
        }
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
//        controlView.setRectCorner(corner:  [.topLeft, .topRight], radii: CGSize.init(width: 24, height: 24))
        retryButton.setGradient(colors: [.hexColor("#72F4E6"), .hexColor("#374BEC")], index: 0)
    }

    override func addNotifaction() {
        super.addNotifaction()
        addPlayNotifaction()
        addTaskNotifaction()
        addSleepNotifacion()
    }

    func addSleepNotifacion() {
        PlayerManager.shared.$sleepModel.receive(on: DispatchQueue.main).sink { [weak self] model in
            guard let self = self else {
                return
            }
            self.topView.timeButton.setTitle(model.countTime.hhmmss, for: .normal)
            self.topView.timeButton.isSelected = model.isOpen

        }.store(in: &cancellable)

        NotificationCenter.default.addObserver(self, selector: #selector(updateLikeInfo), name: kDataChangedNotifactionName, object: nil)

        NotificationCenter.default.addObserver(self, selector: #selector(retryAudio(notify:)), name: kSingleVideoFailNotifactionName, object: nil)
    }

    @objc func retryAudio(notify: Notification) {
        if let videoId = notify.object as? String,
           videoId == PlayerManager.shared.currentVideo?.videoId {
            TSNewDownloadManager.shared.retryDownload(videoId: videoId, isAudio: true) { [weak self] downloader in
                guard let self = self else { return }
                self.downloader = downloader
                self.updateDownloader(id: videoId)
            }
        }
    }

    func addPlayNotifaction() {
        playControl.viewModel.$loadState.receive(on: DispatchQueue.main).sink { [weak self] state in
            guard let self = self else { return }
            self.loadingStateChangeHandler(state: state)
        }.store(in: &cancellable)

        playControl.viewModel.$currentTime.receive(on: DispatchQueue.main).sink { [weak self] timeValue in
            guard let self = self else { return }
            self.controlView.updateTime(currentTime: timeValue, duration: self.playControl.player.duration)

        }.store(in: &cancellable)

        playControl.viewModel.$playStatus.receive(on: DispatchQueue.main).sink { [weak self] status in
            guard let self = self else { return }
            self.playStatusChangeHandler(status)

        }.store(in: &cancellable)

        playControl.viewModel.$loopMode.receive(on: DispatchQueue.main).sink { [weak self] loop in
            guard let self = self else { return }
            self.controlView.playModelButton.setImage(UIImage(named: loop.icon), for: .normal)
        }.store(in: &cancellable)

        playControl.viewModel.$currentVideo.receive(on: DispatchQueue.main).dropFirst().scan((nil, nil)) { previous, current in
            (previous.1, current)
        }.sink { [weak self] oldValue, newValue in
            guard let self = self else { return }

            /// 即将播放的和正在播放的视频是同一个
            if newValue != nil &&
                oldValue?.videoId == newValue?.videoId {
                PlayerManager.shared.showPlayerViewController()
                return
            }

            if let mVideo = newValue {
                self.controlView.updateVideoInfo(video: mVideo)
                PlayerManager.shared.miniBar.updateVideoInfo(video: mVideo, state: .pause)
                self.updateDownloader(id: mVideo.videoId ?? "")
            } else {
                self.controlView.resetVideoInfo()
                self.controlView.resetProgress()
                PlayerManager.shared.miniBar.resetVideoInfo()
            }
            self.updatePlaceHoderView(video: newValue, status: .stopped)
            self.updateNavibar(video: newValue)
            if let videoId = newValue?.videoId {
                UserDefaults.standard.set(videoId, forKey: "LAST_PlAYED_VIDEO_ID")
            }
            NotificationCenter.default.post(name: kDataChangedNotifactionName, object: nil)
        }.store(in: &cancellable)
    }

    func updatePlaceHoderView(video: TSVideo?, status: VLCMediaPlayerState) {
        guard let mVideo = video else {
            return
        }
        playControl.player.view.isHidden = false
        if mVideo.isOnline {
            placeHolderView.isHidden = true
            playControl.player.presentView.placeholderImageView.kf.setImage(with: mVideo.iconUrl)
        } else {
            playControl.player.presentView.placeholderImageView.image = nil
            if mVideo.isAudio {
                placeHolderView.isHidden = false
                placeHolderView.iconView.image = UIImage(named: "ic_default")
                playControl.player.view.isHidden = true
            } else {
                placeHolderView.iconView.kf.setImage(with: mVideo.iconUrl)
                if mVideo.videoStatus == .cached {
                    placeHolderView.isHidden = true
                } else {
                    switch status {
                    case .stopped, .opening:
                        placeHolderView.isHidden = false
                    default:
                        placeHolderView.isHidden = true
                    }
                }
            }
        }
    }

    func loadingStateChangeHandler(state: TSLoadState) {
        /// 展示状态
        if state == .loading {
            retryButton.isHidden = true
            showLoading()
        } else if state == .fail {
            hideLoading()
            retryButton.isHidden = false
        } else if state == .success {
            retryButton.isHidden = true
            hideLoading()
        } else {
            retryButton.isHidden = true
            hideLoading()
        }

        /// 按钮是否可用
        if state == .loading {
            controlView.playButton.playingState = .pause
            controlView.playlistButton.isEnabled = false
            controlView.progressView.isUserInteractionEnabled = false
        } else {
            controlView.playlistButton.isEnabled = true
            controlView.progressView.isUserInteractionEnabled = true
        }
    }

    fileprivate func playStatusChangeHandler(_ status: VLCMediaPlayerState) {
        if status == .playing {
            controlView.playButton.playingState = .playing
            updatePlaceHoderView(video: playControl.viewModel.currentVideo, status: status)
            if let video = playControl.viewModel.currentVideo {
                PlayerManager.shared.miniBar.updateVideoInfo(video: video, state: .playing)
            }
        } else if status == .paused || status == .ended || status == .stopped {
            controlView.playButton.playingState = .pause
            if let video = playControl.viewModel.currentVideo {
                PlayerManager.shared.miniBar.updateVideoInfo(video: video, state: .pause)
            }
        } else if status == .buffering {
            /// 缓冲了展示loading
            if !playControl.player.isPlaying && !controlView.progressView.isDragging {
                showLoading()
            } else {
                hideLoading()
            }
        }
    }

    func addTaskNotifaction() {
        // 单个完成回调
        NotificationCenter.default.addObserver(self, selector: #selector(updateDownoloadStatus(notify:)), name: kGroupDownloadFinishNotifactionName, object: nil)
    }

    func updateDownloader(id: String) {
        if let downloader = TSNewDownloadManager.shared.fetchDownloader(identifier: id) {
            downloaderCancellable.removeAll()
            self.downloader = downloader
            downloader.$progress.receive(on: DispatchQueue.main).sink { [weak self] progress in
                self?.controlView.downloadButton.progressView.set(progress: Double(progress))
            }.store(in: &downloaderCancellable)

            downloader.$downloadState.receive(on: DispatchQueue.main).sink { state in
                self.controlView.setDownloadButtonStates(status: state)
            }.store(in: &downloaderCancellable)
        } else {
            downloaderCancellable.removeAll()
            downloader = nil
            if let video = TSVideoOperator.shared.dataManager.fetchVideo(videoId: id) {
                controlView.setDownloadButtonStates(status: video.videoStatus.asChunkDownloadStatus)
            } else {
                controlView.setDownloadButtonStates(status: .idle)
            }
        }
    }

    @objc func updateDownoloadStatus(notify: Notification) {
        if let videoId = notify.object as? String,
           let video = TSVideoOperator.shared.dataManager.fetchVideo(videoId: videoId),
           let currentVideo = TSVideoOperator.shared.playerViewModel.currentVideo {
            if videoId == currentVideo.videoId {
                controlView.setDownloadButtonStates(status: video.videoStatus.asChunkDownloadStatus)
            }
        }
    }

    @objc func showMoreOperation() {
        let vc = CWOperateViewController(types: [.like, .addPlaylist, .share, .deleteVideo])
        vc.modalPresentationStyle = .overFullScreen
        vc.operteItem = playControl.viewModel.currentVideo
        PlayerManager.shared.rootVc?.present(vc, animated: true)
    }

    func countDownTime() {
        timer?.invalidate()
        timer = nil
        PlayerManager.shared.sleepModel.isOpen = true
        timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { _ in
            PlayerManager.shared.sleepModel.countTime -= 1

            if PlayerManager.shared.sleepModel.countTime < 1 {
                /// 倒计时结束，暂停播放器
                self.playControl.pause()
                self.stopTimer()
            }
        }
    }

    func stopTimer() {
        PlayerManager.shared.sleepModel.isOpen = false
        PlayerManager.shared.sleepModel.countTime = 0
        timer?.invalidate()
        timer = nil
    }

    func addActionTargets() {
        topView.backButton.addTarget(self, action: #selector(swapDown), for: .touchUpInside)
        topView.timeButton.addTarget(self, action: #selector(showSleepTimeController), for: .touchUpInside)
        topView.moreButton.addTarget(self, action: #selector(showMoreOperation), for: .touchUpInside)

        controlView.playButton.addTarget(self, action: #selector(playButtonAction), for: .touchUpInside)
        controlView.listButton.addTarget(self, action: #selector(playlistButtonAction), for: .touchUpInside)
        controlView.nextButton.addTarget(self, action: #selector(nextButtonAction), for: .touchUpInside)
        controlView.lastButton.addTarget(self, action: #selector(lastButtonAction), for: .touchUpInside)
        controlView.playModelButton.addTarget(self, action: #selector(playModeButtonAction), for: .touchUpInside)
        controlView.downloadButton.addTarget(self, action: #selector(downloadButtonAction), for: .touchUpInside)
        controlView.playlistButton.addTarget(self, action: #selector(addToPlaylistAction), for: .touchUpInside)
        controlView.favouriteButton.addTarget(self, action: #selector(favouriteButtonAction), for: .touchUpInside)
        retryButton.addTarget(self, action: #selector(reloadVideo), for: .touchUpInside)
        controlView.progressView.tappedExeBlock = { [weak self] _, progress in

            self?.controlView.progressView.value = progress
            let durationTime = (self?.playControl.player.duration ?? 0)
            let currentTime = durationTime * progress
            print("duration---\(durationTime),current ---- \(currentTime)")
            self?.controlView.updateTime(currentTime: currentTime, duration: durationTime)
            self?.playControl.pause()
            self?.playControl.seekToProgress(progress: progress) { [weak self] _ in
                self?.playControl.play()
            }
        }
        // 创建下滑手势识别器
        let swipeDownGesture = UISwipeGestureRecognizer(target: self, action: #selector(swapDown))
        swipeDownGesture.direction = .down

        // 添加手势识别器到 myView
        view.addGestureRecognizer(swipeDownGesture)
    }

    @objc func reloadVideo() {
        playControl.viewModel.reloadCurrentVideo()
    }

    override func addChildren() {
        super.addChildren()
        controlView.progressView.delegate = self
        placeHolderView.isHidden = true
        addChild(playControl)
        view.addSubview(topView)
        view.addSubview(playControl.view)
        view.addSubview(controlView)
        view.addSubview(placeHolderView)
        view.addSubview(customLoading)
        view.addSubview(retryButton)
        view.bringSubviewToFront(topView)
    }

    override func makeConstarints() {
        super.makeConstarints()
        topView.snp.makeConstraints { make in
            make.top.equalTo(view.safeAreaLayoutGuide.snp.top)
            make.leading.trailing.equalToSuperview()
            make.height.equalTo(44)
        }
        let vRadio = UIScreen.kScreenHeight / 896.0
        playControl.view.snp.makeConstraints { make in
            make.top.equalTo(topView.snp.bottom).offset(100 * vRadio)
            make.leading.trailing.equalToSuperview()
            make.height.equalTo(playControl.view.snp.width).multipliedBy(9.0 / 16.0)
        }

        retryButton.snp.makeConstraints { make in
            make.center.equalTo(playControl.view)
            make.height.equalTo(40)
            make.width.equalTo(100)
        }

        customLoading.snp.makeConstraints { make in
            make.center.equalTo(playControl.view)
        }

        placeHolderView.iconView.contentMode = .scaleAspectFit
        placeHolderView.snp.makeConstraints { make in
            make.top.equalTo(topView.snp.bottom).offset(100 * vRadio)
            make.leading.trailing.equalToSuperview()
            make.height.equalTo(playControl.view.snp.width).multipliedBy(9.0 / 16.0)
        }

        controlView.snp.makeConstraints { make in
            make.leading.trailing.bottom.equalToSuperview()
            make.bottom.equalTo(view.safeAreaLayoutGuide.snp.bottom).offset(-40)
        }
    }
}

//
/// targets
extension PlayDetailViewController {
    @objc func swapDown() {
        PlayerManager.shared.hiddePlayerViewController()
    }

    @objc func playButtonAction() {
        /// 播放器没源，但是有当前播放歌曲
        if PlayerManager.shared.player?.playControl.player.urlAsset == nil, let current = PlayerManager.shared.currentVideo {
            PlayerManager.shared.playVideo(video: current, list: [], scene: .local, onceAdKey: "")
        } else {
            PlayerManager.shared.playOrPause()
        }
    }

    @objc func playlistButtonAction() {
        let vc = PlayDetailListViewContoller()
        vc.viewModel.videos = playControl.viewModel.currentVideos
        vc.viewModel.recommendDatas = playControl.viewModel.recommendDatas
        vc.viewModel.playScene = playControl.viewModel.scene
        vc.modalPresentationStyle = .overFullScreen
        present(vc, animated: true)
    }

    @objc func nextButtonAction() {
        if FitManager.isAr {
            playControl.playLast()
        } else {
            playControl.playNext()
        }
    }

    @objc func lastButtonAction() {
        if FitManager.isAr {
            playControl.playNext()
        } else {
            playControl.playLast()
        }
    }

    @objc func playModeButtonAction() {
        playControl.viewModel.loopMode = playControl.viewModel.loopMode.nextMode()
        THUD.toast(playControl.viewModel.loopMode.rawValue, at: .center)
    }

    @objc func favouriteButtonAction() {
        if let video = TSVideoOperator.shared.playerViewModel.currentVideo {
            if video.isFavorite {
                TSVideoOperator.shared.dataManager.dislikeCurrentVideo { _ in
                    updateLikeInfo()
                }
            } else {
                TSVideoOperator.shared.dataManager.likeCurrentVideo { _ in
                    updateLikeInfo()
                }
            }
        }
    }

    @objc func updateLikeInfo() {
        if let video = TSVideoOperator.shared.playerViewModel.currentVideo {
            controlView.favouriteButton.isSelected = video.isFavorite
        }
    }

    @objc func downloadButtonAction(sender: DownloadButton) {
        if let video = TSVideoOperator.shared.playerViewModel.currentVideo,
           let videoId = video.videoId {
            switch sender.downloadState {
            case .idle(isAnimate: false), .idle(isAnimate: true):
                if PurchaseManager.default.isVip {
                    TSNewDownloadManager.shared.downloadVideo(videoId: videoId, isAudio: false) { [weak self] downloader in
                        self?.downloader = downloader
                        self?.updateDownloader(id: videoId)
                    }
                } else {
                    let loading = ADLoadingViewController()
                    loading.adScene = .downloadReward
                    loading.finishedHandler = { [weak self] finished in
                        if finished {
                            TSNewDownloadManager.shared.downloadVideo(videoId: videoId, isAudio: false) { [weak self] downloader in
                                self?.downloader = downloader
                                self?.updateDownloader(id: videoId)
                            }
                        }
                    }
                    PlayerManager.shared.rootVc?.present(loading, animated: false)
                }
                break
            case .pause:
                TSNewDownloadManager.shared.resumeTask(id: videoId) { [weak self] downloader in
                    self?.downloader = downloader
                    self?.updateDownloader(id: videoId)
                }

            case .downloading:
                TSNewDownloadManager.shared.pauseTask(id: videoId) { [weak self] downloader in
                    self?.downloader = downloader
                    self?.updateDownloader(id: videoId)
                }

            case .retry:
                TSNewDownloadManager.shared.retryDownload(videoId: videoId, isAudio: false) { [weak self] downloader in
                    self?.downloader = downloader
                    self?.updateDownloader(id: videoId)
                }
                break
            default:
                break
            }
        }
    }

    // 调用这个方法来显示加载圈
    func showLoading() {
        customLoading.start()
    }

    // 调用这个方法来隐藏加载圈
    func hideLoading() {
        customLoading.stop()
    }

    @objc func addToPlaylistAction() {
        if let video = TSVideoOperator.shared.playerViewModel.currentVideo {
            let addVc: AddPlayListViewController = AddPlayListViewController(video: video)
            addVc.addSuccessBlock = {
                THUD.toast("Added Successfully".localized())
            }
            addVc.modalPresentationStyle = .overFullScreen
            PlayerManager.shared.rootVc?.present(addVc, animated: true)
        }
    }

    @objc func showSleepTimeController() {
        let times: [Int] = [15, 30, 60, 90, 120]
        // 创建 UIAlertController 实例
        let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)

        for time in times {
            let option = UIAlertAction(title: "\(time) minutes", style: .default) { [weak self] _ in
                PlayerManager.shared.sleepModel.countTime = Double(time) * 60.0
                self?.countDownTime()
            }
            alertController.addAction(option)
        }

        // 添加关闭按钮
        let offAction = UIAlertAction(title: "Turn Off".localized(), style: .default) { _ in
            self.stopTimer()
        }
        offAction.setValue(UIColor.red, forKey: "titleTextColor")
        alertController.addAction(offAction)

        let cancelAction = UIAlertAction(title: "Cancel".localized(), style: .cancel) { _ in }
        alertController.addAction(cancelAction)

        present(alertController, animated: true, completion: nil)
    }
}
