import vwo_insights_ios_reactnative_sdk
import React
import Foundation

@objc(VwoInsightsReactNativeSdk)
class VwoInsightsReactNativeSdk: RCTEventEmitter, VWOIntegrationCallback  {
  
  
 var ScreenName = ""

    var callback: RCTResponseSenderBlock?
    let EVENT_NAME_KEY = "EVENTNAME"
    let EVENT_DATA_KEY = "EVENTDATA"
    var isInitSuccess = false
    @objc(config:withB:withC:)
    func config(accountID: NSString, AppID: NSString, userID: NSString
    ){
        VWO.enableLog(logLevel: .all)
        VWO.setHybridEnable(name: "React")
        VWO.configure(accountId: accountID as String, sdkKey: AppID as String, userId: userID as String){ result in
            switch result{
            case .success(_):
            self.isInitSuccess = true
                print("VWO initi success")
            case .failure(let error):
                print("VWO initi failed \(error)")
            }
        }
    }
@objc(sdkVersion:)
  func sdkVersion(version: String){
        var screenListData = [String: Any]()
        screenListData["sdkVersion"] = version
        screenListData["screenList"] = []
        VWO.setHybridEnable(name: "React")
        VWO.setHybrideSDKDetails(isReactSDK : true, values : screenListData)
    }
@objc(startRecording)
  func startRecording(){
    if (isInitSuccess) {
       print("startRecording function call")
        VWO.startSessionRecording()
    }
    }
@objc(stopRecording)
  func stopRecording(){
       print("stopRecording function call")
      VWO.stopSessionRecording()
  }

@objc(pauseRecording)
  func pauseRecording(){
    if (isInitSuccess) {
       print("pauseRecording function call")
        VWO.pauseRecording()
    }
    }
@objc(resumeRecording)
  func resumeRecording(){
       print("resumeRecording function call")
      VWO.resumeRecording()
  }
    // fetch integration data

@objc(setScreenName:)
  func setScreenName(screenName: String){
    self.ScreenName = screenName
      VWO.setScreenName(name: screenName as String)
  }

   @objc(customAttribute:)
  func customAttribute(customData: [String:Any]){
     
    var dicData : [String: Any] = [:]
     
    for (key, value) in customData {
      if let numberValue = value as? NSNumber {
        let isBool = (numberValue.stringValue == "0" || numberValue.stringValue == "1") &&
        (numberValue === kCFBooleanTrue || numberValue === kCFBooleanFalse)
         
        if isBool {
          dicData[key] = numberValue.boolValue
        } else {
          if let intValue = value as? Int {
            dicData[key] = intValue
          } else if let floatValue = value as? CGFloat {
            dicData[key] = floatValue
          } else if let doubleValue = value as? Double {
            dicData[key] = doubleValue
          }
        }
      } else if let stringValue = value as? String {
        dicData[key] = stringValue
      } else if let dictValue = value as? [String:Any] {
        dicData[key] = dictValue
      }
    }
     
    VWO.triggerSyncVisitorPropEvent(visitorData: dicData)
  }
    @objc(customEvent:withB:withC:)
    func customEvent(eventName :String, customData: Dictionary<String, Any>, customBoolData: Dictionary<String, Bool>){
     var newMergedDict = customData
      for (key, value) in customBoolData {
          newMergedDict[key] = value
      }
        var updatedCustomData = [String: Any]()
        updatedCustomData[EVENT_NAME_KEY] = eventName
        updatedCustomData[EVENT_DATA_KEY] = newMergedDict

     let eventName = updatedCustomData[EVENT_NAME_KEY] as? String
     let eventData = updatedCustomData[EVENT_DATA_KEY] as? [String: Any]

     if let eventName = eventName, let value = eventData, !eventName.isEmpty {
         
         var preparedEvents: [String: Any] = [:]
         value.forEach { k, v in
             
             preparedEvents[k] = v
         }

         VWO.triggerCustomEvent(customEventName: eventName, customData: preparedEvents)
         print("sendCustomEvent key \(eventName) data (\(preparedEvents))")
     } else {
         
         print("Key is nil or empty, or value is nil")
     }  
 }
    @objc(customVariable:)
 func customVariable(customData: NSDictionary){
     var dict = Dictionary<String, String>()
     for (key, value) in customData {
         if let key = key as? String {
              if let stringValue = value as? String {
                 dict[key] = stringValue
              } 
         }
     }
     VWO.setCustomVariable(customVariable: dict);
 }
@objc
  func getSessionURL(_ source: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
      if let sessionURL = VWO.getSessionURL(source: IntegrationsList(rawValue: source)?.rawValue ?? "") {
     resolve(sessionURL)
   } else {

      let error = NSError(domain: "", code: 200, userInfo: nil)
      reject("no_url", "Could not generate session URL", error)
   }
  }
  
  enum IntegrationsList : String{
      case CRASHLYTICS = "CRASHLYTICS"
      case MIXPANEL = "MIXPANEL"
      case MOENGAGE = "MOENGAGE"
      
      func getName() -> String {
          return self.rawValue
      }
  }

    @objc func enableVWOIntegrations(_ callback: @escaping RCTResponseSenderBlock) {
        // Perform some tasks
        // Trigger the callback with the enum value
          self.callback = callback
          VWO.enableIntegrations(integrationCallback: self)
    }
        //Export the module to React Native
    @objc override static func requiresMainQueueSetup() -> Bool {
        return true
    }
    
    func onVWOIntegrationCompleted(integrations: [vwo_insights_ios_reactnative_sdk.IntegrationsList]) {

       for integration in integrations {
         let sessionURL = VWO.getSessionURL(source: integration.rawValue)
           if(sessionURL == nil){
               print("Session URL could not be generated - VWO Insights is not initialized. Please ensure that VWO Insights is properly initialized before attempting to generate the session URL. Refer to the documentation for initialization instructions.")
               return
           }
          
           switch integration {
           case .CRASHLYTICS :
               sendEvent(withName: "onSessionRefresh", body: ["CRASHLYTICS":["session_url": "\(sessionURL!)"]])
              
           case .MOENGAGE:
               sendEvent(withName: "onSessionRefresh", body: ["MOENGAGE":["session_url": "\(sessionURL!)"]])
              
           case .MIXPANEL:
               sendEvent(withName: "onSessionRefresh", body: ["MIXPANEL":["session_url": "\(sessionURL!)"]])
              
               @unknown default:
                   print("Unsupported Integration enum!")
           }
       }
        
    }

    override func supportedEvents() -> [String]! {
      return ["onSessionRefresh"]
    }

    @objc(constantsToExport)
    override func constantsToExport() -> [AnyHashable: Any]!{
      return [:]
    }

}

