//
//  WokaFMVC.swift
//  WOKA
//
//  Created by MacBook Pro on 01/08/24.
//

import UIKit
import AVFoundation
import Alamofire
import GoogleMobileAds

class WokaFMVC: UIViewController {
    
    @IBOutlet weak var roundView: UIView!
    @IBOutlet weak var mainView: UIView!
    @IBOutlet weak var playBtn: UIButton!
    @IBOutlet weak var volPlusBtn: UIButton!
    @IBOutlet weak var volMinusBtnn: UIButton!
    @IBOutlet weak var activityIndicator: UIActivityIndicatorView!
    @IBOutlet weak var blackView: UIView!
    @IBOutlet weak var adView: UIView!
    
    var vm = WokaFMVM()

    deinit {
        vm.playerItem.removeObserver(self, forKeyPath: "status")
        vm.player.removeObserver(self, forKeyPath: "timeControlStatus")
        vm.playerItem.removeObserver(self, forKeyPath: "isPlaybackBufferEmpty")
        vm.playerItem.removeObserver(self, forKeyPath: "isPlaybackLikelyToKeepUp")
        
        vm.player?.pause()
        NotificationCenter.default.removeObserver(self,name: UIApplication.didEnterBackgroundNotification, object: nil)
        NotificationCenter.default.removeObserver(self,name: UIApplication.willEnterForegroundNotification, object: nil)
        
        // Deactivate the audio session if needed
        do {
            try AVAudioSession.sharedInstance().setActive(false, options: .notifyOthersOnDeactivation)
        } catch {
            print("Failed to deactivate audio session: \(error.localizedDescription)")
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        vm.vc = self
        vm.initView()
        NotificationCenter.default.addObserver(self,selector: #selector(appDidEnterBackground),name: UIApplication.didEnterBackgroundNotification,object: nil)
        NotificationCenter.default.addObserver(self,selector: #selector(appWillEnterForeground),name: UIApplication.willEnterForegroundNotification,object: nil)
    }
    
    // MARK: - App LifeCycle HAndler

    @objc func appDidEnterBackground() {
        vm.setupNowPlayingInfo()
        vm.setupRemoteCommandCenter()
        if let postID = AuthFunc.shareInstance.staticURLs?.liveFmData?.id {
            let duration = DateFormatterLib.dateDifferenceINT(date1: vm.startTimeStamp, date2: Date())
            AuthFunc.shareInstance.userVideoView(postID: postID, postType: PostType.FM.rawValue, duration: duration, catID: 0) { [weak self] isDone in
                guard let self else{return}
                if isDone{
                    vm.startTimeStamp = Date()
                }
            }
        }
    }
    
    @objc func appWillEnterForeground(){
        vm.stopMPNowPlayin()
    }
    
    @IBAction func playBtnTapped(_ sender: UIButton) {
        PersistentStorage.shared.addRadioCount()
        if sender == playBtn{
            if sender.image(for: .normal)?.pngData() == UIImage(named: "Reload")?.pngData(){
                // when user reloads check for internet connection
                if !(NetworkReachabilityManager()?.isReachable ?? false){
                    return
                }
                vm.retryConnect()
            } else if sender.image(for: .normal)?.pngData() == UIImage(named: "PlayButton")?.pngData(){
                vm.player.play()
            }else{
                vm.player.pause()
            }
        }
    }
        
    @IBAction func volumeBtnTapped(_ sender: UIButton) {
        PersistentStorage.shared.addRadioCount()
        switch sender{
        case volPlusBtn:
            if vm.player.volume == 1 {
                sender.isEnabled = false
                return
            }
            
            volMinusBtnn.isEnabled = true
            let newVolume = min(vm.player.volume + 0.2, 1.0)
            vm.player.volume = newVolume
        case volMinusBtnn:
            if vm.player.volume == 0.0 {
                sender.isEnabled = false
                return
            }
            
            volPlusBtn.isEnabled = true
            let newVolume = max(vm.player.volume - 0.2, 0.0)
            vm.player.volume = newVolume
        default:
            break
        }
    }
    
    @IBAction func closeBtnTapped(_ sender: UIButton) {
        PersistentStorage.shared.addRadioCount()
        if let postID = AuthFunc.shareInstance.staticURLs?.liveFmData?.id {
            let duration = DateFormatterLib.dateDifferenceINT(date1: vm.startTimeStamp, date2: Date())
            AuthFunc.shareInstance.userVideoView(postID: postID, postType: PostType.FM.rawValue, duration: duration, catID: 0) { _ in}
        }
        self.dismiss(animated: true)
    }
    
    func startMonitoring(){
        NetworkReachibility.shared.startMonitoring { [weak self] isConnected in
            guard let self else{return}
            switch isConnected{
            case true: // if network is connected than stop
                // when internet is back we have to setup player again
                NetworkReachibility.shared.stopMonitoring()
                vm.setupPlayer()
                addObservers()
                vm.setupAudioSession()
            case false:
                // if there is no internet connection prompt user and show reload icon
                self.toast(msg: "Lost Connection.", time: 1.4)
                activityIndicator.stopAnimating()
                playBtn.setImage(UIImage(named: "Reload"), for: .normal)
                playBtn.isEnabled = true
            }
        }
    }
        
    func addObservers() {
        // Observe the player's status
        vm.playerItem.addObserver(self, forKeyPath: "status", options: [.new, .old], context: nil)
        
        // Observe the player's time control status
        vm.player.addObserver(self, forKeyPath: "timeControlStatus", options: [.new, .old], context: nil)
        
        // Observe buffering status
        vm.playerItem.addObserver(self, forKeyPath: "isPlaybackBufferEmpty", options: [.new, .old], context: nil)
        vm.playerItem.addObserver(self, forKeyPath: "isPlaybackLikelyToKeepUp", options: [.new, .old], context: nil)
    }
    
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        if keyPath == "status" {
            if vm.playerItem.status == .readyToPlay {
                print("FM is ready to play")
                vm.player.play()
            } else if vm.playerItem.status == .failed {
                if vm.retryCount < 4{
                    vm.retryCount += 1
                    vm.retryConnect()
                    print("retry fm connect :-", vm.retryCount)
                    return
                }
                print("FM failed to load")
                activityIndicator.stopAnimating()
                playBtn.setImage(UIImage(named: "Reload"), for: .normal)
                playBtn.isEnabled = true
            }
        } else if keyPath == "timeControlStatus" {
            switch vm.player.timeControlStatus {
            case .playing:
                print("FM is playing")
                activityIndicator.stopAnimating()
                playBtn.isEnabled = true
                playBtn.setImage(UIImage(named: "PauseButton"), for: .normal)
            case .paused:
                print("FM is paused")
                playBtn.setImage(UIImage(named: "PlayButton"), for: .normal)
            case .waitingToPlayAtSpecifiedRate:
                activityIndicator.startAnimating()
                playBtn.isEnabled = false
                
                if !(NetworkReachabilityManager()?.isReachable ?? false){
                    startMonitoring()
                }
                print("FM is buffering 1 ")
            @unknown default:
                break
            }
        } else if keyPath == "isPlaybackBufferEmpty" {
            if vm.playerItem.isPlaybackBufferEmpty {
                print("FM is buffering 2")
                playBtn.isEnabled = false
                activityIndicator.startAnimating()
                startMonitoring()
            }
        } else if keyPath == "isPlaybackLikelyToKeepUp" {
            if vm.playerItem.isPlaybackLikelyToKeepUp {
                print("FM is likely to keep up with the playback")
            }
        }
    }
}


extension UIButton {
    func applyGradientBtn(colors: [UIColor], startPoint: CGPoint, endPoint: CGPoint) {
        // Remove existing gradient layer if any
        self.layer.sublayers?.filter { $0 is CAGradientLayer }.forEach { $0.removeFromSuperlayer() }
        
        // Create a new CAGradientLayer instance
        let gradientLayer = CAGradientLayer()
        
        // Set the frame of the gradient layer to match the bounds of the button
        gradientLayer.frame = self.bounds
        
        // Convert the array of UIColor objects to an array of CGColor objects
        gradientLayer.colors = colors.map { $0.cgColor }
        
        // Set the start and end points of the gradient
        gradientLayer.startPoint = startPoint
        gradientLayer.endPoint = endPoint
        
        // Insert the gradient layer at the bottom of the button's layer hierarchy
        self.layer.insertSublayer(gradientLayer, at: 0)
        
        // Bring image and title layers to front
        self.bringSubviewToFront(self.imageView!)
        self.bringSubviewToFront(self.titleLabel!)
    }
}

// MARK: - Google Ad Banner Delegate

extension WokaFMVC : GADBannerViewDelegate{
    func bannerViewDidReceiveAd(_ bannerView: GADBannerView) {
        print("bannerViewDidReceiveAd")
        adView.isHidden = false
        bannerView.alpha = 0
        bannerView.backgroundColor = #colorLiteral(red: 0.01960784314, green: 0, blue: 0.2196078431, alpha: 1)
        UIView.animate(withDuration: 0.2, animations: {
            bannerView.alpha = 1
        })
    }
    
    func bannerView(_ bannerView: GADBannerView, didFailToReceiveAdWithError error: Error) {
        print("bannerView:didFailToReceiveAdWithError: \(error.localizedDescription)")
    }
    
    func bannerViewDidRecordImpression(_ bannerView: GADBannerView) {
        print("bannerViewDidRecordImpression")
    }
    
    func bannerViewWillPresentScreen(_ bannerView: GADBannerView) {
        print("bannerViewWillPresentScreen")
    }
    
    func bannerViewWillDismissScreen(_ bannerView: GADBannerView) {
        print("bannerViewWillDIsmissScreen")
    }
    
    func bannerViewDidDismissScreen(_ bannerView: GADBannerView) {
        print("bannerViewDidDismissScreen")
    }
}

////Update system volume
//extension MPVolumeView {
//    static func setVolume(_ volume: Float) {
//        let volumeView = MPVolumeView()
//        let slider = volumeView.subviews.first(where: { $0 is UISlider }) as? UISlider
//
//        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.01) {
//            slider?.value = volume
//        }
//    }
//}
