//
//  AuthFunc.swift
//  WOKA
//
//  Created by Bilal on 26/04/2024.
//

import Foundation
import AVFoundation
import UIKit
import OneSignalFramework
import Alamofire

enum GetSet{
    case get
    case set
}

enum AdsEnum : String{
    case themeOne = "theme-1"
    case themeTwo = "theme-2"
    case shop_super_category = "shop-super-category"
    case web_series = "web-series"
    case karaoke = "karaoke"
    case audioBooks = "audio-books"
    case games = "games"
}

class AuthFunc{
    
    /**
     This is not for external use!
     This should only be used for login, registration, Auth Process process & userData Extraction.
     */
    
    var player: AVQueuePlayer?
    var playerLooper: AVPlayerLooper?
    
    /*
     This will hold user type
     */
    var userType = UserType.adult
    
    /*
     This will hold the user data
     */
    var userData : UserDataDM.ResultData?
    
    /*
     This holds the live url and fm url
     */
    var staticURLs : URLStaticDM?
    
    /*
     This holds the ads
     */
    var adsData : AdsDM?
    
    
    /*
     This holds the language selected by user
     */
    var languageSelected = LocalizedEnum.english {
        didSet {
            NotificationCenter.default.post(name: .languageDidChange, object: nil)
        }
    }
    
    var authID = String()
    var authPass = String()
    
    /*
     This will hold the theme selected
     */
    var selectedTheme = ThemeSelect.theme1
    
    /*
     This is temporary variable. Make it emtpy when the registration is finished.
     */
    var regData = UserRegPostModel()
    
    // Singleton instance of AuthFunc
    static let shareInstance = AuthFunc()
    
    //Handling Time Changes on Home
    var timePeriods = [TimePeriod]()
    
    // Returns the device's UUID
    func getDeviceUUID() -> String{
        /* 
         UIDevice.current.name             // e.g. "My iPhone"
         UIDevice.current.model            // e.g. @"iPhone", @"iPod touch"
         UIDevice.current.localizedModel   // localized version of model
         UIDevice.current.systemName       // e.g. @"iOS"
         UIDevice.current.systemVersion    // e.g. @"15.5"
         */
        return UIDevice.current.identifierForVendor!.uuidString
    }
    
    //This will return oneplayer signal id
    func getOneSignalID() -> String{
        return OneSignal.User.pushSubscription.id ?? ""
    }
    
    // Sets authentication ID and password from the app's info dictionary
    func setAuthIDPass(){
        if let id = Bundle.main.infoDictionary?["API_KEY_ID"] as? String{
            authID = id
        }
        
        if let pass = Bundle.main.infoDictionary?["API_KEY_PASS"] as? String{
            authPass = pass
        }
    }
    
    func checkLogin() -> Bool{
        let isLoginned = UserDefaults.standard.bool(forKey: K.UserDefaultsStruct.isUserLogined)
        return isLoginned
    }
    
    /*
     Logout PopUP Handling
     */
    func guestUserLoginPopUp() -> Bool{
        if AuthFunc.shareInstance.getUserType() == 3{
            let sb = UIStoryboard(name: K.StoryBoard.customAlerts, bundle: nil)
            let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.CustomAlerts.logoutPopupVC) as! LogoutPopupVC
            vcPush.modalPresentationStyle = .overCurrentContext
            vcPush.modalTransitionStyle = .crossDissolve
            UIApplication.topViewController()?.present(vcPush, animated: true)
            return true
        }
        return false
    }
    
    /*
     This func will return the access token saved at the time of login
     */
    func getAccessToken() -> String{
        let accessToken = UserDefaults.standard.string(forKey: K.UserDefaultsStruct.userAccessToken)
        return accessToken ?? ""
    }
    
    /*
     Return user ID from Saved user data
     */
    
    func getUserID() -> String{
        let userID = AuthFunc.shareInstance.userData?.id?.toString()
        return userID ?? ""
    }
    
    
    // MARK: - Get & Set the User Type
    func getUserType() -> Int?{
        /*
         1- kid , 2 - guardian , 3 - guest
         */
        let language = UserDefaults.standard.integer(forKey: K.UserDefaultsStruct.userType)
        return language
    }
    
    func setUserType(user : Int){
        UserDefaults.standard.setValue(user, forKey: K.UserDefaultsStruct.userType)
    }
    
    // MARK: - Get & Set the Default Language

    func getDefaultLanguage() -> LocalizedEnum?{
        let language = UserDefaults.standard.string(forKey: K.UserDefaultsStruct.defaultLanguage)
        switch language {
        case LocalizedEnum.hindi.rawValue:
            return .hindi
        case LocalizedEnum.english.rawValue:
            return .english
        default:
            return .english
        }
    }
    
    func setDefaultLanguage(language : LocalizedEnum){
        AuthFunc.shareInstance.languageSelected = language
        UserDefaults.standard.setValue(language.rawValue, forKey: K.UserDefaultsStruct.defaultLanguage)
    }
    
    // MARK: - Login , Logout Defaults

    func logout(){
        //Reset All to defaults
        UserDefaults.standard.setValue(nil, forKey: K.UserDefaultsStruct.themeDefault)
        UserDefaults.standard.setValue(nil, forKey: K.UserDefaultsStruct.isUserLogined)
        UserDefaults.standard.setValue(nil, forKey: K.UserDefaultsStruct.userAccessToken)
        UserDefaults.standard.setValue(nil, forKey: K.UserDefaultsStruct.userType)
        userData = nil
        CartDataCache.shareInstance.removeAll()
        selectedTheme = .theme1
    }
    
    func loginDefaults(data : UserDataDM.ResultData){
        AuthFunc.shareInstance.userData = data
        UserDefaults.standard.set(true, forKey: K.UserDefaultsStruct.isUserLogined)
        UserDefaults.standard.set(data.rememberToken, forKey: K.UserDefaultsStruct.userAccessToken)
        UserDefaults.standard.set(data.userType?.toInt(), forKey: K.UserDefaultsStruct.userType)
        UIApplication.setRootView(SideMenuController.instantiate(from: .Home))
    }
    
    // MARK: - Get the Static URL's
    
    func getStaticURLs(onCompletion: ((Bool) -> Void)? = nil){
        NetworkManager.shareInstance.apiRequest(url: APIEndPoints.StaticURLs.live_streaming, method: .get) { [weak self](result : Result<BaseResponseModel<URLStaticDM>, NetworkManager.APIError>) in
            switch result{
            case .success(let data):
                guard let self else{return}
                switch data.success{
                case 0:
                    onCompletion?(false)
                case 1:
                    guard let data = data.data else{return}
                    AuthFunc.shareInstance.staticURLs = data
                    onCompletion?(true)
                default:
                    onCompletion?(false)
                }
            case .failure(_):
                onCompletion?(false)
            }
        }
    }

    // MARK: - Get AD's
    
    func getAds(onCompletion: ((Bool) -> Void)? = nil){
        let params : Parameters = ["start" : "0",
                                   "limit":"0"]
        NetworkManager.shareInstance.apiRequest(url: APIEndPoints.Analytics.get_ad_data, method: .get,parameters: params) { (result : Result<BaseResponseModel<AdsDM>, NetworkManager.APIError>) in
            switch result{
            case .success(let data):
                switch data.success{
                case 0:
                    onCompletion?(false)
                case 1:
                    guard let data = data.data else{return}
                    AuthFunc.shareInstance.adsData = data
                    onCompletion?(true)
                default:
                    onCompletion?(false)
                }
            case .failure(_):
                onCompletion?(false)
            }
        }
    }

}

// MARK: - Language Enum

enum LocalizedEnum : String , CaseIterable{
    case hindi = "hi"
    case english = "en"
}

// MARK: - Enum representing different user types

enum UserType {
    case adult
    case kid
}
