//
//  ThemeTwoVM.swift
//  WOKA
//
//  Created by MacBook Pro on 27/05/24.
//

import UIKit
import AVFoundation
import JWPlayerKit
import Alamofire
import GoogleMobileAds

struct Theme2Struct{
    let imageName : String
    let text : String
}

class ThemeTwoVM{
    
    weak var vc : ThemeTwoVC!
    var liveStreamURL = "https://d3volyx7jx7oal.cloudfront.net/master.m3u8"
    var avPlayer : AVPlayer!
    var playerItem: AVPlayerItem!
    var playerLayer: AVPlayerLayer!
    
    let reachability = NetworkReachabilityManager()
    let monitor = NWPathMonitor()
    let queue = DispatchQueue.global(qos: .background)
    var isNetworkMonitored = false
    var bannerView = GADBannerView()

    /*
     Static cell data
     */
    var cellData = [Theme2Struct(imageName: "WokaFMT2", text: "WOKA FM"),
                    Theme2Struct(imageName: "LiveTVT2", text: "LIVE TV"),
                    Theme2Struct(imageName: "WebSeriesT2", text: "WEB SERIES"),
                    Theme2Struct(imageName: "GamesT2", text: "GAMES"),
                    Theme2Struct(imageName: "AudioBooksT2", text: "AUDIO BOOKS"),
                    Theme2Struct(imageName: "KaraokeT2", text: "KARAOKE"),
                    Theme2Struct(imageName: "ShopT2", text: "SHOP")]
    
    func initView(){
        setupCell()
        setupAvPlayer()
        setUserData()
        
        handleNotificationCenter()
        vc.liveTvView.addTapGesture { [weak self] in
            PersistentStorage.shared.addOthersCount()
            guard let self else{return}
            self.playLiveTV()
        }
        
        // configuring the google ads.
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.3, execute: { [weak self] in
            guard let self else{return}
            AdReusable.sharedInstance.setupBannerAd(bannerView: bannerView, in: vc.adView, adUnitID: K.GoogleAdIDs.splashBanner1, viewController: self.vc, height: 8, width: 15)
        })
    }
    
    private func handleNotificationCenter(){
        NotificationCenter.default.addObserver(self, selector: #selector(self.reloadTheme), name: NSNotification.Name(rawValue: K.NotificationCenterReloads.reloadTheme), object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(appDidEnterBackground), name: UIApplication.didEnterBackgroundNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(appWillEnterForeground), name: UIApplication.willEnterForegroundNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(self.viewPush(notification:)), name: NSNotification.Name(rawValue: K.NotificationCenterReloads.themeTwoPush), object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(handleRouteChange(_:)), name: AVAudioSession.routeChangeNotification, object: nil)
    }
        
    // MARK: - This will handle all clicks for modules
    
    // This comes from Explore WOKA CLicks
    @objc func viewPush(notification: Notification){
        if let userInfo = notification.userInfo, let action = userInfo["action"] as? TopViewPush {
            checkType(action: action)
        }
    }
    
    // Made a common func to check which module to push
    func checkType(action : TopViewPush){
        switch action {
        case .webseries:
            let sb = UIStoryboard(name: K.StoryBoard.webSeries, bundle: nil)
            let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.WebSeries.webSeriesVC) as! WebSeriesVC
            vc.navigationController?.pushViewController(vcPush, animated: true)
        case .audioBooks:
            let sb = UIStoryboard(name: K.StoryBoard.audioBooks, bundle: nil)
            let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.AudioBooks.audioBookHomeVC) as! AudioBookHomeVC
            vc.navigationController?.pushViewController(vcPush, animated: true)
        case .games:
            let sb = UIStoryboard(name: K.StoryBoard.Games, bundle: nil)
            let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Games.gamesListVC) as! GamesListVC
            vc.navigationController?.pushViewController(vcPush, animated: true)
        case .karaoke:
            let sb = UIStoryboard(name: K.StoryBoard.Karaoke, bundle: nil)
            let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Karaoke.karaokeListingVC) as! KaraokeListingVC
            vc.navigationController?.pushViewController(vcPush, animated: true)
        case .shop:
            let sb = UIStoryboard(name: K.StoryBoard.shop, bundle: nil)
            let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Shop.shopListingVC) as! ShopListingVC
            vc.navigationController?.pushViewController(vcPush, animated: true)
        case .liveTV:
            playLiveTV()
        case .blogs:
            let sb = UIStoryboard(name: K.StoryBoard.theme, bundle: nil)
            let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Theme.blogsVC) as! BlogsVC
            vc.navigationController?.pushViewController(vcPush, animated: true)
        case .radio:
            let sb = UIStoryboard(name: K.StoryBoard.wokaFM, bundle: nil)
            let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.WokaFM.wokaFMVC) as! WokaFMVC
            vcPush.modalPresentationStyle = .overCurrentContext
            vcPush.modalTransitionStyle = .crossDissolve
            vc.present(vcPush, animated: true)
        }
    }

    // MARK: - Notification Center Handlers
    
    @objc func reloadTheme(){
        self.vc.delegate?.didPressSwitchButton(from: self.vc)
    }
    
    @objc func appDidEnterBackground() {
        // Code to execute when the app enters the background
        print("App entered background")
        self.avPlayer.pause()
    }
    
    @objc func appWillEnterForeground() {
        // Code to execute when the app enters the foreground
        print("App will enter foreground")
        self.avPlayer.play()
    }
    
    @objc func handleRouteChange(_ notification: Notification) {
        guard let userInfo = notification.userInfo,
              let reasonValue = userInfo[AVAudioSessionRouteChangeReasonKey] as? UInt,
              let reason = AVAudioSession.RouteChangeReason(rawValue: reasonValue) else {
            return
        }
        
        switch reason {
        case .oldDeviceUnavailable:
            // Headphones unplugged, avoid pausing if desired
            avPlayer?.play() // Resume playing if paused

        case .newDeviceAvailable:
            // Headphones plugged in, you may want to take specific actions if needed
            avPlayer?.play() // Resume playing if paused
            
        default:
            break
        }
    }
    
    // MARK: - Live TV

    func playLiveTV(){
        Utilities.startProgressHUD(msg: "Loading...")
        print("tapped")
        let vc = self.vc.storyboard?.instantiateViewController(identifier: K.StoryBoardID.Theme.playerVC) as! PlayerVC
        
        guard let data = AuthFunc.shareInstance.staticURLs , let liveStreamData = data.liveData?.first else{
            self.vc.toast(msg: "Issue with live streaming", time: 2)
            return
        }
        var url = String()
        var title = String()
        
        if AuthFunc.shareInstance.languageSelected == .english{
            url = liveStreamData.liveURL?.hdURLEn ?? ""
            title = liveStreamData.name?.titleEn ?? ""
        }else{
            url = liveStreamData.liveURL?.hdURLHin ?? ""
            title = liveStreamData.name?.titleHin ?? ""
        }
        
        do {
            // Ensure the liveStreamURL is valid
            guard let liveStreamURL = URL(string: url) else {
                print("Invalid live stream URL")
                Utilities.dismissProgressHUD()
                return
            }
            
            let videoSourceBuilder = try JWVideoSourceBuilder()
            //                    .defaultVideo(true)
                .file(liveStreamURL)
                .label(title)
                .build()
            
            // Create a JWPlayerItem
            let item = try JWPlayerItemBuilder()
            //                    .file(liveStreamURL)
                .videoSources([videoSourceBuilder])
                .title(title)
                .build()
            
            // Create a JWPlayerConfiguration
            let config = try JWPlayerConfigurationBuilder()
                .playlist(items: [item])
                .preload(JWPreload(rawValue: 20) ?? .none)
                .autostart(true)
                .build()
            
            vc.config = config
            vc.dismissTapped = self.tapped
            vc.contentType = .liveStream
            if let streamID = AuthFunc.shareInstance.staticURLs?.liveData?.first?.id{
                vc.vm.videoIDs = [streamID]
            }
            vc.modalPresentationStyle = .fullScreen
            vc.modalTransitionStyle = .crossDissolve
            
            // Present the PlayerVC
            self.vc.present(vc, animated: true) { [weak self] in
                guard let self else{return}
                stopLiveStream()
            }
        } catch {
            print("Error creating JWPlayer configuration: \(error)")
            Utilities.dismissProgressHUD()
        }
        
        // Dismiss the progress HUD after the view controller presentation
        Utilities.dismissProgressHUD()
    }
    
    func tapped(){
        Timer.scheduledTimer(withTimeInterval: 0.2, repeats: false) { _ in
            self.startLiveStream()
            self.vc.liveTvView.layoutIfNeeded()
        }
        print("Sadasd")
    }
    
    func startLiveStream(){
        avPlayer.play()
        avPlayer.volume = 0
    }
    
    func stopLiveStream(){
        avPlayer.pause()
    }
    
    func setUserData(){
        guard let data = AuthFunc.shareInstance.userData else{return}
        //set the first name as the name
        /*
         Check User Type,
         Dont show username if the user type is guest
         */
        switch data.userType{
        case "1": // child
            vc.nameLabel.text = data.fullname?.components(separatedBy: " ").first
            vc.notificationBtn.isHidden = false
        case "2" : // adult
            vc.nameLabel.text = data.fullname?.components(separatedBy: " ").first
            vc.notificationBtn.isHidden = false
        case "3": // Guest
            vc.nameLabel.text = ""
            vc.notificationBtn.isHidden = true
            break
        default:
            break
        }
        
        if let avatar = data.avtarURL{
//            vc.avatarImage.imageURL("https://wokaland.com/secret-panel-10102023/hidden-admin-portal-20092023/storage/app/public/uploads/avtar/avatar2.png?d=1716889852")
            vc.avatarImage.imageURL(avatar)
        }else{
            vc.avatarImage.image = UIImage(named: "DefaultAvatar")
        }
    }
    
    func setupAvPlayer(){
        /*
         Av Player Setup
         */
        guard let data = AuthFunc.shareInstance.staticURLs , let liveStreamData = data.liveData?.first else{
            vc.toast(msg: "Issue with live streaming", time: 2)
            return
        }
        var url = String()
        
        if AuthFunc.shareInstance.languageSelected == .english{
            url = liveStreamData.liveURL?.hdURLEn ?? ""
        }else{
            url = liveStreamData.liveURL?.hdURLHin ?? ""
        }
        
        guard let streamURL = URL(string: url) else{return}
        startStopActivity(isStart: true)
        playerItem = AVPlayerItem(url: streamURL)

        // Create AVPlayer with the stream URL
        avPlayer = AVPlayer(playerItem: playerItem)
        //        avPlayer.isMuted = true
        
        // Create AVPlayerLayer
        playerLayer = AVPlayerLayer(player: avPlayer)
        playerLayer.videoGravity = .resizeAspectFill // You can set different videoGravity as per your need
        
        playerLayer.frame = vc.liveTvView.bounds
        vc.liveTvView.layer.addSublayer(playerLayer)
        vc.liveTvView.bringSubviewToFront(vc.liveTVActivityIndicator)
        vc.liveTvView.layoutIfNeeded()
        avPlayer.play()
        avPlayer.volume = 0
        
        //Add Observer after the player is setup
        avPlayer.addObserver(vc, forKeyPath: "timeControlStatus", options: [.new, .old], context: nil)
        playerItem.addObserver(vc, forKeyPath: "status", options: [.new, .old], context: nil)
    }
    
    func setData(){
        
//        playerLayer.frame = self.vc.liveTvView.bounds
        
        guard let data = AuthFunc.shareInstance.userData else{return}
        //set the first name as the name
        /*
         Check User Type,
         Dont show username if the user type is guest
         */
        switch data.userType{
        case "1": // child
            vc.nameLabel.text = data.fullname?.components(separatedBy: " ").first
        case "2" : // adult
            vc.nameLabel.text = data.fullname?.components(separatedBy: " ").first
        case "3": // Guest
            vc.nameLabel.text = ""
            break
        default:
            break
        }
        
    }
    
    // MARK: - start stop activity Indicator
    
    func startStopActivity(isStart : Bool){
        DispatchQueue.main.async { [weak self] in
            guard let self else{return}
            if isStart{
                vc.liveTVActivityIndicator.startAnimating()
            }else{
                vc.liveTVActivityIndicator.hidesWhenStopped = true
                vc.liveTVActivityIndicator.stopAnimating()
            }
        }
    }

    // MARK: - SetupCell
    
    func setupCell(){
        vc.collectionView.register(UINib(nibName: K.CellIdentifier.Theme.homeExploreCell, bundle: nil), forCellWithReuseIdentifier: K.CellIdentifier.Theme.homeExploreCell)
        vc.collectionView.delegate = vc.self
        vc.collectionView.dataSource = vc.self
    }
}
