//
//  FIRRemoteManagement.swift


import Foundation
import FirebaseRemoteConfig

enum FIRRemoteKeys : String{
    //Cipher key for API
    case data1320
    case isForceAppUpdate
    case isForceAppUpdateDescription
    
    //Intro screen
    case IntroTitle1Info
    case IntroTitle2Info
    case IntroSubTitle1Info
    case IntroSubTitle2Info
    
    //Rating review
    case custom_review_popup_text
    case isShow_CustomReviewPopup
    case isShow_NativeReviewPopup
    
    //Delete account
    case delete_user_desc
    case delete_user_title
    
    //Manage Ads
    case isShowBannerAds
    case isShowInterstitialAds
    case isShowInterstitialAdsCount
    case isShowOpenAds
    case isShowOpenAdsCount
    case isShowOpenAdsOnLaunch
    case isShowOpenAdsOnLaunchCount
    case isShowOpenAdsFirstTime
    
    case loginAttemptCount
    case native_review_count
    //Extra Key
    case title
    case fontSize
    case textColor
}

class FIRRemoteManagement : NSObject{
    
    static let shared = FIRRemoteManagement()
    
    private var remoteConfig: RemoteConfig!
    
    var cipherKerForAPI : String{
        get{
            let strValue = (self.remoteConfig[FIRRemoteKeys.data1320.rawValue].stringValue ?? "").assignDefaultValueIfEmpty(defaultVal: APICipherKeyData.defaultCipherKey)
            
            return self.getPasswordForEncryption(strValue: strValue, startIndex: APICipherKeyData.startIndex, endIndex: APICipherKeyData.endIndex)
        }
    }
    
    var isForceAppUpdate : Bool{
        get{
            return self.remoteConfig[FIRRemoteKeys.isForceAppUpdate.rawValue].boolValue
        }
    }
    
    var isForceAppUpdateDescription: String{
        get {
            return (self.remoteConfig[FIRRemoteKeys.isForceAppUpdateDescription.rawValue].stringValue ?? "").assignDefaultValueIfEmpty(defaultVal: "A new version of Live Pic Widget is available. Please update to latest version.")
        }
    }

    //MARK:  - Introduction screen info
    
    //Title 1
    fileprivate var dictIntroTitle1Info: [String : Any] {
        get {
            
            let val = (self.remoteConfig[FIRRemoteKeys.IntroTitle1Info.rawValue].stringValue ?? "").assignDefaultValueIfEmpty(defaultVal: "title:Welcome to 'Live Pic Widget'; fontSize:25; textColor:FFFFFF".jsonString)
            
            return convertToDictionary(from: val)

            
        }
    }
    var isInterstitialAdsCount : String{
        get{
            return self.remoteConfig[FIRRemoteKeys.isShowInterstitialAdsCount.rawValue].stringValue ?? "0"
        }
    }
    var isShowBannerAds : Bool{
        get{
            return self.remoteConfig[FIRRemoteKeys.isShowBannerAds.rawValue].boolValue
        }
    }
    
    var isShowInterstitialAds : Bool{
        get{
            return self.remoteConfig[FIRRemoteKeys.isShowInterstitialAds.rawValue].boolValue
        }
    }
    
    var loginAttemptCount : Int{
        get{
            let defaultValue:Int = 3
            return Int(self.checkEmptyIntValue(actualValue: self.remoteConfig[FIRRemoteKeys.loginAttemptCount.rawValue].numberValue, defaultValue: defaultValue))
           // return Int(truncating: self.remoteConfig[FIRRemoteKeys.loginAttemptCount.rawValue].numberValue)
        }
    }
    
    var isShowOpenAds : Bool{
        get{
            return self.remoteConfig[FIRRemoteKeys.isShowOpenAds.rawValue].boolValue
        }
    }
    
    var isShowOpenAdsOnLaunch : Bool{
        get{
            return self.remoteConfig[FIRRemoteKeys.isShowOpenAdsOnLaunch.rawValue].boolValue
        }
    }
    
    var isShowOpenAdsFirstTime : Bool{
        get{
            return self.remoteConfig[FIRRemoteKeys.isShowOpenAdsFirstTime.rawValue].boolValue
        }
    }
    
    var isShowOpenAdsCount : String{
        get{
            return self.remoteConfig[FIRRemoteKeys.isShowOpenAdsCount.rawValue].stringValue ?? "0"
        }
    }
    
    var isShowOpenAdsOnLaunchCount : String{
        get{
            return self.remoteConfig[FIRRemoteKeys.isShowOpenAdsOnLaunchCount.rawValue].stringValue ?? "0"
        }
    }
    
    var nativeReviewCount : Int{
        get{
            return Int(self.remoteConfig[FIRRemoteKeys.native_review_count.rawValue].stringValue ?? "5") ?? 5
        }
    }
    
    
    var introTitle1: String {
        get {
            return dictIntroTitle1Info[FIRRemoteKeys.title.rawValue] as? String ?? ""
        }
    }
    
    var introTitle1FontColor: String {
        get {
            return dictIntroTitle1Info[FIRRemoteKeys.textColor.rawValue] as? String ?? ""
        }
    }
    
    var introTitle1FontSize: CGFloat {
        get {
            guard let n = NumberFormatter().number(from: (dictIntroTitle1Info[FIRRemoteKeys.fontSize.rawValue] as? String ?? "")) else { return DeviceType.ISPAD ? CGFloat(28) : CGFloat(25)}
            return CGFloat(truncating: n)
        }
    }
    
    
    //Title 2
    fileprivate var dictIntroTitle2Info: [String : Any] {
        get {
            let val = (self.remoteConfig[FIRRemoteKeys.IntroTitle2Info.rawValue].stringValue ?? "").assignDefaultValueIfEmpty(defaultVal: "title:Send Reactions and DMs; fontSize:25; textColor:FFFFFF".jsonString)

            return convertToDictionary(from: val)
        }
    }
    
    var introTitle2: String {
        get {
            return dictIntroTitle2Info[FIRRemoteKeys.title.rawValue] as? String ?? ""
        }
    }
    
    var introTitle2FontColor: String {
        get {
            return dictIntroTitle2Info[FIRRemoteKeys.textColor.rawValue] as? String ?? ""
        }
    }
    
    var introTitle2FontSize: CGFloat {
        get {
            guard let n = NumberFormatter().number(from: (dictIntroTitle2Info[FIRRemoteKeys.fontSize.rawValue] as? String ?? "")) else { return CGFloat(25)}
            return CGFloat(truncating: n)
        }
    }
    
    func checkEmptyIntValue(actualValue: NSNumber, defaultValue: Int) -> Int {
           if actualValue == 0{
               return defaultValue
           }
           return Int(truncating: actualValue)
       }
    
    //Subtitle 1
    fileprivate var dictIntrosubTitle1Info: [String : Any] {
        get {
            let val = (self.remoteConfig[FIRRemoteKeys.IntroSubTitle1Info.rawValue].stringValue ?? "").assignDefaultValueIfEmpty(defaultVal: "title:Share pics, photos and pictures through your and your friends' Home Screens.; fontSize:15; textColor:858585".jsonString)

            return convertToDictionary(from: val)
        }
    }
    
    var introsubTitle1: String {
        get {
            return dictIntrosubTitle1Info[FIRRemoteKeys.title.rawValue] as? String ?? ""
        }
    }
    
    var introsubTitle1FontColor: String {
        get {
            return dictIntrosubTitle1Info[FIRRemoteKeys.textColor.rawValue] as? String ?? ""
        }
    }
    
    var introsubTitle1FontSize: CGFloat {
        get {
            guard let n = NumberFormatter().number(from: (dictIntrosubTitle1Info[FIRRemoteKeys.fontSize.rawValue] as? String ?? "")) else { return CGFloat(25)}
            return CGFloat(truncating: n)
        }
    }
    
    //Subtitle 2
    fileprivate var dictIntrosubTitle2Info: [String : Any] {
        get {
            let val = (self.remoteConfig[FIRRemoteKeys.IntroSubTitle2Info.rawValue].stringValue ?? "").assignDefaultValueIfEmpty(defaultVal: "title:Reply with photos, send reactions or private message your friends.; fontSize:15; textColor:858585".jsonString)

            return convertToDictionary(from: val)
        }
    }
    
    var introsubTitle2: String {
        get {
            return dictIntrosubTitle2Info[FIRRemoteKeys.title.rawValue] as? String ?? ""
        }
    }
    
    var introsubTitle2FontColor: String {
        get {
            return dictIntrosubTitle2Info[FIRRemoteKeys.textColor.rawValue] as? String ?? ""
        }
    }
    
    var introsubTitle2FontSize: CGFloat {
        get {
            guard let n = NumberFormatter().number(from: (dictIntrosubTitle2Info[FIRRemoteKeys.fontSize.rawValue] as? String ?? "")) else { return CGFloat(25)}
            return CGFloat(truncating: n)
        }
    }
    
    
    //MARK: - Rating review
    
    var isShow_CustomReviewPopup : Bool{
        get{
            return self.remoteConfig[FIRRemoteKeys.isShow_CustomReviewPopup.rawValue].boolValue
        }
    }
    
    var isShow_NativeReviewPopup : Bool{
        get{
            return self.remoteConfig[FIRRemoteKeys.isShow_NativeReviewPopup.rawValue].boolValue
        }
    }
        
    var custom_review_popup_text: String {
        get {
            return (self.remoteConfig[FIRRemoteKeys.custom_review_popup_text.rawValue].stringValue ?? "").assignDefaultValueIfEmpty(defaultVal: "title:Enjoying LivePicWidget App? Please share your experience!; fontSize:15; textColor:FFFFFF".jsonString)
        }
    }
    
    //MARK: - Delete Account Info
    
    var delete_user_title: String{
        get {
            return (self.remoteConfig[FIRRemoteKeys.delete_user_title.rawValue].stringValue ?? "").assignDefaultValueIfEmpty(defaultVal: Alert_Message.deleteAccTitle)
        }
    }
    
    var delete_user_desc: String{
        get {
            return (self.remoteConfig[FIRRemoteKeys.delete_user_desc.rawValue].stringValue ?? "").assignDefaultValueIfEmpty(defaultVal: Alert_Message.deleteAccDesc)
        }
    }
    
    
    private override init() {
        super.init()
        remoteConfig = RemoteConfig.remoteConfig()
        let remoteConfigSettings = RemoteConfigSettings()
        remoteConfig.configSettings = remoteConfigSettings
    }
    
    func fetchConfig(completion: (() -> ())? = nil) {
        let expirationDuration = 0

        remoteConfig.fetch(withExpirationDuration: TimeInterval.init(expirationDuration)) { (status, error) -> Void in
            if status == .success {
                debugPrint("Config fetched!")
                self.remoteConfig.activate() { (changed, error) in
                  // ...
                    
                    completion?()
                }
              } else {
                debugPrint("Config not fetched")
                debugPrint("Error: \(error?.localizedDescription ?? "No error available.")")
              }
        }
    }
    
    func getPasswordForEncryption(strValue : String, startIndex : Int, endIndex : Int) -> String {
        
        let startIndexNew = strValue.index(strValue.startIndex, offsetBy: startIndex)
        
        let endIndexNew = strValue.index(strValue.startIndex, offsetBy: endIndex)
                
        let strPwd = strValue[startIndexNew..<endIndexNew]
        
        return String(strPwd)
        
    }
    
    fileprivate func convertToDictionary(from text: String) -> [String: Any] {
        guard let data = text.data(using: .utf8) else { return [:] }
        var result = [String : Any]()
        if let dict = try? JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.allowFragments) as? String {
            dict.components(separatedBy: "; ").forEach({ (entry) in
                let keyValueArray = entry.components(separatedBy: ":")
                return result[keyValueArray[0]] = keyValueArray[1]
            })
        }
        return result
    }
}

extension String{
    func assignDefaultValueIfEmpty(defaultVal: String) -> String {
        if self == "" {
            return defaultVal
        }
        return self
    }
}
