//
//  MapplsIntouchApi.swift
//  mappls-react-native-intouch
//
//  Created by ceinfo on 11/03/21.
//

import Foundation
import MapplsAPIKit
import MapplsAPICore
import MapplsIntouch
import CoreLocation

@objc(MapplsIntouchApi)
class MapplsIntouchApi: NSObject {
    
    @objc static func requiresMainQueueSetup() -> Bool {
        return false
    }
    
    @objc func initializeApisSdk(_ map:NSDictionary) -> Void {
        
        if map["mapSDKKey"] != nil  && map["restAPIKey"] != nil && map["clientId"] != nil && map["clientSecret"] != nil {
            
            let mapSdkKey = map["mapSDKKey"] as? String
            let restAPIKey = map["restAPIKey"] as? String
            let clientId = map["clientId"] as? String
            let clientSecret = map["clientSecret"] as? String
    
             MapplsAccountManager.setMapSDKKey(mapSdkKey)
            MapplsAccountManager.setRestAPIKey(restAPIKey)
            MapplsAccountManager.setClientId(clientId)
            MapplsAccountManager.setClientSecret(clientSecret)
            MapplsAccountManager.setGrantType("client_credentials") //eg.client_credentials
        }
        
    }

    @objc func getDevices(_ map:NSDictionary,reslover resolve: @escaping RCTPromiseResolveBlock,rejecter reject: @escaping RCTPromiseRejectBlock ) -> Void {
        
        if map["deviceIds"] != nil {
           let deviceIds =  map["deviceIds"] as! NSArray
           let includeInActive = map["includeInActive"] as! Bool
           let ignoreBeacon = map["ignoreBeacon"] as! Bool
           let lastUpdateTime = map["lastUpdateTime"] as! NSNumber
        
            IntouchApis.shared.getDevices(listOfDeviceIds: deviceIds as! [Int], includeInActive: includeInActive, ignoreBeacon: ignoreBeacon, lastUpdateTime: lastUpdateTime.stringValue) { (response, error) in

          if let error = error {
            reject("Error", error.localizedDescription, nil)
                  }
              if let result = response
                {
                do {
                    let encodedData = try JSONEncoder().encode(result)
                    let jsonString = String(data: encodedData,encoding: .utf8)
                    let nsDict = self.convertStringToDictionary(text: jsonString!,rejecter: reject)
                    resolve(nsDict!)
                } catch {
                    reject("Error", error.localizedDescription, nil)
                }

            }
            }
           
        }else {
            let includeInActive = map["includeInActive"] as! Bool
            let ignoreBeacon = map["ignoreBeacon"] as! Bool
            let lastUpdateTime = map["lastUpdateTime"] as! NSNumber
            
            IntouchApis.shared.getDevices(includeInActive: includeInActive, ignoreBeacon: ignoreBeacon, lastUpdateTime: lastUpdateTime.stringValue) { (response, error) in

                if let error = error {
                  reject("Error", error.localizedDescription, nil)
                        }
                    if let result = response
                      {
                      do {
                          let encodedData = try JSONEncoder().encode(result)
                          let jsonString = String(data: encodedData,encoding: .utf8)
                          let nsDict = self.convertStringToDictionary(text: jsonString!,rejecter: reject)
                          resolve(nsDict!)
                      } catch {
                          reject("Error", error.localizedDescription, nil)
                      }

                  }
            }
        }
            
        }
    
    
    @objc func getDevice(_ map:NSDictionary,reslover resolve: @escaping RCTPromiseResolveBlock,rejecter reject: @escaping RCTPromiseRejectBlock ) -> Void {
        
        
        if map["deviceId"] != nil && map["lastUpdateTime"] != nil{
            
            let deviceId =  map["deviceId"] as! NSNumber
            let lastUpdateTime = map["lastUpdateTime"] as! NSNumber
            
            IntouchApis.shared.getDevices(deviceId: Int(truncating: deviceId), lastUpdateTime: lastUpdateTime.stringValue) { (response, error) in
                          if let error = error {
                            reject("Error", error.localizedDescription, nil)
                    }
                if let result = response
                  {
                    do {
                        let encodedData = try JSONEncoder().encode(result)
                        let jsonString = String(data: encodedData,encoding: .utf8)
                       let nsDict = self.convertStringToDictionary(text: jsonString!,rejecter: reject)
                        resolve(nsDict!)
                    } catch {
                        reject("Error", error.localizedDescription, nil)
                    }

              }
                            }
        }else{
            reject("Error", "provide all params", nil)
            
        }
        
        
    }
    
    
    @objc func getDevicesInfo(_ map:NSDictionary,reslover resolve: @escaping RCTPromiseResolveBlock,rejecter reject: @escaping RCTPromiseRejectBlock ) -> Void {
        if map["deviceIds"] != nil {
            let deviceIds =  map["deviceIds"] as! NSArray
            IntouchApis.shared.getDevicesInfo(deviceIds: deviceIds as! [Int]) { (response, error) in
                           if let error = error {
                            reject("Error", error.localizedDescription, nil)
                    }
                if let result = response
                  {
                    do {
                        let encodedData = try JSONEncoder().encode(result)
                        let jsonString = String(data: encodedData,encoding: .utf8)
                        let nsDict = self.convertStringToDictionary(text: jsonString!,rejecter: reject)
                        resolve(nsDict!)
                    } catch {
                        reject("Error", error.localizedDescription, nil)
                    }
              }
                   }
            
        } else {
            IntouchApis.shared.getDevicesInfo( completionHandler: { (response, error) in
                           if let error = error {
                            reject("Error", error.localizedDescription, nil)
                    }
                if let result = response
                  {
                    do {
                        let encodedData = try JSONEncoder().encode(result)
                        let jsonString = String(data: encodedData,encoding: .utf8)
                        let nsDict = self.convertStringToDictionary(text: jsonString!,rejecter: reject)
                        resolve(nsDict!)
                    } catch {
                        reject("Error", error.localizedDescription, nil)
                    }
              }
                   })
            
        }
        
    }
    
    
    @objc func getLocationsEvents(_ map:NSDictionary,reslover resolve: @escaping RCTPromiseResolveBlock,rejecter reject: @escaping RCTPromiseRejectBlock ) -> Void {
        
        if map["deviceId"] != nil && map["startTime"] != nil && map["endTime"] != nil && map["skipPeriod"] != nil  {
           
            let deviceId = map["deviceId"] as! NSNumber
            let startTime = map["startTime"] as! NSNumber
            let endTime = map["endTime"] as! NSNumber
            let skipPeriod = map["skipPeriod"] as! NSNumber
            
            IntouchApis.shared.getLocationsEvent(deviceId: Int(truncating: deviceId), startTime: Double(truncating: startTime), endTime: Double(truncating: endTime), skipPeriod: Int(truncating: skipPeriod) ,completionHandler: {

                (response, error) in
                if let error = error {
                    reject("Error", error.localizedDescription, nil)
                        }
                    if let result = response
                      {
                        do {
                            let encodedData = try JSONEncoder().encode(result)
                            let jsonString = String(data: encodedData,encoding: .utf8)
                            let nsDict = self.convertStringToDictionary(text: jsonString!,rejecter: reject)
                            resolve(nsDict!)
                        } catch {
                            reject("Error", error.localizedDescription, nil)
                        }

                    }
            })
        }else{
            reject("getLocationsEvents Error: ", "provide all params", nil)
        }
        
    }
    
    @objc func getDrive(_ map:NSDictionary,reslover resolve: @escaping RCTPromiseResolveBlock,rejecter reject: @escaping RCTPromiseRejectBlock ) -> Void {
        if map["deviceId"] != nil && map["startTime"] != nil && map["endTime"] != nil {
            
               let mDeviceId = map["deviceId"] as! NSNumber
               let mStartTime = map["startTime"] as! NSNumber
               let mEndTime = map["endTime"] as! NSNumber
               
            IntouchApis.shared.getDriveData(deviceId: Int(truncating: mDeviceId), startTime: Double(truncating: mStartTime), endTime: Double(truncating: mEndTime)) { (driveResponse, error) in
                if let error = error {
                    reject("Error", error.localizedDescription, nil)
                        }
                    if let result = driveResponse
                      {
                        do {
                            let encodedData = try JSONEncoder().encode(result)
                            let jsonString = String(data: encodedData,encoding: .utf8)
                            let nsDict = self.convertStringToDictionary(text: jsonString!,rejecter: reject)
                            resolve(nsDict!)
                        } catch {
                            reject("Error", error.localizedDescription, nil)
                        }

                    }
            }

           
            
        }
        
    }
    
    @objc func createGeoFence(_ map:NSDictionary,reslover resolve: @escaping RCTPromiseResolveBlock,rejecter reject: @escaping RCTPromiseRejectBlock ) -> Void {
        
        if map["geofenceName"] != nil && map["geofencePoints"] != nil {
            
            let geofenceName = map["geofenceName"] as! String
            let geofencePoints = map["geofencePoints"] as! NSArray
            
            let coordinates = createCLLocationArray(points: geofencePoints)
            let mGeometry = IntouchGeometryPolygon(points: coordinates)
            let mGeofence = IntouchPolygonGeofence(name: geofenceName, geometry: mGeometry)
            let mGeofenceoption = IntouchGeofenceOptions(geofence: mGeofence)

            IntouchApis.shared.createGeoFence(geofence: mGeofenceoption) { (status, error) in
                if let error = error {
                    reject("Error", error.localizedDescription, nil)
                }else{
                    let dict = NSMutableDictionary()
                    dict["id"] = status
                    resolve(dict)
                }
            }
            
        } else if map["geofenceName"] != nil && map["geofencePoint"] != nil && map["range"] != nil {
            
            let geofenceName = map["geofenceName"] as! String
            let range = map["range"] as! NSNumber
            let geofencePoint = map["geofencePoint"] as! NSArray
            let lat = geofencePoint[1] as! NSNumber
            let lng = geofencePoint[0] as! NSNumber
            
            let mGeometry = IntouchGeometryPoint(point: CLLocation(latitude: Double(truncating: lat), longitude: Double(truncating: lng)))

            let mGeofence = IntouchPointGeofence(name: geofenceName, buffer: range, geometry:
                                mGeometry)
            let mGeofenceoption = IntouchGeofenceOptions(geofence: mGeofence)

            IntouchApis.shared.createGeoFence(geofence: mGeofenceoption) { (status, error) in
                if let error = error {
                    reject("Error", error.localizedDescription, nil)
                }else{
                    let dict = NSMutableDictionary()
                    dict["id"] = status
                    resolve(dict)
                }
            }
            
        } else if map["geofenceName"] != nil && map["geofencePoint"] != nil  {
            
            let geofenceName = map["geofenceName"] as! String
            let geofencePoint = map["geofencePoint"] as! NSArray
            let lat = geofencePoint[1] as! NSNumber
            let lng = geofencePoint[0] as! NSNumber
            
            let mGeometry = IntouchGeometryPoint(point: CLLocation(latitude: Double(truncating: lat), longitude: Double(truncating: lng)))

            let mGeofence = IntouchPointGeofence(name: geofenceName, geometry:
                                mGeometry)
            let mGeofenceoption = IntouchGeofenceOptions(geofence: mGeofence)

            IntouchApis.shared.createGeoFence(geofence: mGeofenceoption) { (status, error) in
                if let error = error {
                    reject("Error", error.localizedDescription, nil)
                        }else{
                            let dict = NSMutableDictionary()
                            dict["id"] = status
                            resolve(dict)
                        }
            }

            
        } else {
            
            reject("createGeofence Error", "please provide params", nil)
        }
        
    }
    
    @objc func getGeoFences(_ map:NSDictionary,reslover resolve: @escaping RCTPromiseResolveBlock,rejecter reject: @escaping RCTPromiseRejectBlock ) -> Void {
        
        if map["ignoreGeometry"] != nil && map["geofenceIds"] != nil{
            
            let mIgnoreGeometry = map["ignoreGeometry"] as! Bool
            let mGeofenceIds = map["geofenceIds"] as! [Int]
            
            IntouchApis.shared.getAllGeoFences(geofenceIds: mGeofenceIds, ignoreGeometry: mIgnoreGeometry) { (response, error) in
                if let error = error {
                    reject("Error", error.localizedDescription, nil)
                        }
                    if let result = response
                      {
                        do {
                            let encodedData = try JSONEncoder().encode(result)
                            let jsonString = String(data: encodedData,encoding: .utf8)
                            let nsDict = self.convertStringToDictionary(text: jsonString!,rejecter: reject)
                            resolve(nsDict!)
                        } catch {
                            reject("Error", error.localizedDescription, nil)
                        }

                    }
            }
            
            
        } else if map["geofenceId"] != nil && map["ignoreGeometry"] != nil {
            
            let mIgnoreGeometry = map["ignoreGeometry"] as! Bool
            let mGeofenceId = map["geofenceId"] as! Int

            IntouchApis.shared.getAllGeoFences(geofenceID: mGeofenceId, ignoreGeometry: mIgnoreGeometry) { (response, error) in
                if let error = error {
                    reject("Error", error.localizedDescription, nil)
                        }
                    if let result = response
                      {
                        do {
                            let encodedData = try JSONEncoder().encode(result)
                            let jsonString = String(data: encodedData,encoding: .utf8)
                            let nsDict = self.convertStringToDictionary(text: jsonString!,rejecter: reject)
                            resolve(nsDict!)
                        } catch {
                            reject("Error", error.localizedDescription, nil)
                        }

                    }
          }
        } else if map["ignoreGeometry"] != nil {
            let mIgnoreGeometry = map["ignoreGeometry"] as! Bool
            
            IntouchApis.shared.getAllGeoFences(ignoreGeometry: mIgnoreGeometry) { (response, error) in
                if let error = error {
                    reject("Error", error.localizedDescription, nil)
                        }
                    if let result = response
                      {
                        do {
                            let encodedData = try JSONEncoder().encode(result)
                            let jsonString = String(data: encodedData,encoding: .utf8)
                            let nsDict = self.convertStringToDictionary(text: jsonString!,rejecter: reject)
                            resolve(nsDict!)
                        } catch {
                            reject("Error", error.localizedDescription, nil)
                        }

                    }
            }
            
        } else {
            reject("getGeofence Error ", "Please provide required params", nil)
        }
        
        
    }
    
    
    
    
    //Getting error in case of scuccess
    @objc func updateGeoFence(_ map:NSDictionary,reslover resolve: @escaping RCTPromiseResolveBlock,rejecter reject: @escaping RCTPromiseRejectBlock ) -> Void {
        
        if map["geofenceId"] != nil && map["geofenceName"] != nil && map["geofencePoints"] != nil && map["buffer"] != nil {
            
            let mGeofenceId = map["geofenceId"] as! NSNumber
            let mGeofenceName = map["geofenceName"] as! String
            let mBuffer = map["buffer"] as! NSNumber
            let geofencePoint = map["geofencePoint"] as! NSArray
            let lat = geofencePoint[1] as! NSNumber
            let lng = geofencePoint[0] as! NSNumber
            let mGeometry = IntouchGeometryPoint(point: CLLocation(latitude: Double(truncating: lat), longitude: Double(truncating: lng)))
            let mGeofence = IntouchPointGeofence(name: mGeofenceName, buffer: mBuffer, geometry: mGeometry)
            let geofenceoption = IntouchGeofenceOptions(geofence: mGeofence)

            IntouchApis.shared.updateGeoFences(geofenceaID: Int(truncating: mGeofenceId), geofence: geofenceoption) { (status, error) in
                if let error = error {
                    reject("Error", error.localizedDescription, nil)
                } else {
                    resolve("success")
                }
        }
        
        
        } else if map["geofenceId"] != nil && map["geofenceName"] != nil && map["geofencePoints"] != nil {
            
            let mGeofenceId = map["geofenceId"] as! NSNumber
            let mGeofenceName = map["geofenceName"] as! String
            let geofencePoints = map["geofencePoints"] as! NSArray
            
            let coordinates = createCLLocationArray(points: geofencePoints)
            
            let mGeometry = IntouchGeometryPolygon(points: coordinates)
            let mGeofence = IntouchPolygonGeofence(name: mGeofenceName, geometry: mGeometry)
            let geofenceoption = IntouchGeofenceOptions(geofence: mGeofence)


            IntouchApis.shared.updateGeoFences(geofenceaID: Int(truncating: mGeofenceId), geofence: geofenceoption) { (status, error) in
                if error != nil {
                        }else {
                            resolve("success")
        }
            }
//
            
        } else if map["geofenceId"] != nil && map["geofenceName"] != nil && map["geofencePoint"] != nil  {
            
            let mGeofenceId = map["geofenceId"] as! NSNumber
            let mGeofenceName = map["geofenceName"] as! String
            let geofencePoint = map["geofencePoint"] as! NSArray
            let lat = geofencePoint[1] as! NSNumber
            let lng = geofencePoint[0] as! NSNumber
            let mGeometry = IntouchGeometryPoint(point: CLLocation(latitude: Double(truncating: lat), longitude: Double(truncating: lng)))
            let mGeofence = IntouchPointGeofence(name: mGeofenceName, geometry: mGeometry)
            let geofenceoption = IntouchGeofenceOptions(geofence: mGeofence)

            IntouchApis.shared.updateGeoFences(geofenceaID: Int(truncating: mGeofenceId), geofence: geofenceoption) { (status, error) in
                if let error = error {
                    print("\(error.code)\(error.localizedDescription)")
                        }else {
                            print(status)
                        }
        }
        
        
        } else {
            reject("updateGeofence Error ", "Please provide required params", nil)
            
        }
    }
    
    //Getting error in case of successs
    @objc func deleteGeoFence(_ map:NSDictionary,reslover resolve: @escaping RCTPromiseResolveBlock,rejecter reject: @escaping RCTPromiseRejectBlock ) -> Void {
        
        //Long[] geofenceIds = getLongList(map.getArray("geofenceIds"));
        
        if map["geofenceIds"] != nil {
            let mGeofenceIds = map["geofenceIds"] as! [Int]
            
            IntouchApis.shared.deleteGeofence(geofenceIds:mGeofenceIds) { (status, error) in
                         if let error = error {
                            reject("Error", error.localizedDescription, nil)
                         }else{
                            resolve("success")
                         }
                    }
        
        } else if map["geofenceId"] != nil {
            let mGeofenceId = map["geofenceId"] as! NSNumber
            
            IntouchApis.shared.deleteGeofence(geofenceaID: Int(truncating: mGeofenceId)) { (status, error) in
                         if let error = error {
                            reject("Error", error.localizedDescription, nil)
                         } else{
                            resolve("success")
                         }

                            }

        } else {
            
            reject("deleteGeofence Error ", "Please provide required params", nil)
        }
        
    }
    
    
    @objc func getGeoFenceActivity(_ map:NSDictionary,reslover resolve: @escaping RCTPromiseResolveBlock,rejecter reject: @escaping RCTPromiseRejectBlock ) -> Void {
        
        if map["devicesIds"] != nil && map["geofenceIds"] != nil && map["startTime"] != nil && map["endTime"] != nil {
            let mDeviceIds = map["devicesIds"] as! [Int]
            let mGeofenceIds = map["geofenceIds"] as! [Int]
            let mStartTime = map["startTime"] as! Double
            let mEndTime = map["endTime"] as! Double
            
            
            IntouchApis.shared.getGeoFenceActivity(geofenceIds: mGeofenceIds, devicesIds:mDeviceIds, startTime: mStartTime, endTime: mEndTime) { (response, error) in
                if let error = error {
                    reject("Error", error.localizedDescription, nil)
                        }
                    if let result = response
                      {
                        do {
                            let encodedData = try JSONEncoder().encode(result)
                            let jsonString = String(data: encodedData,encoding: .utf8)
                            let nsDict = self.convertStringToDictionary(text: jsonString!,rejecter: reject)
                            resolve(nsDict!)
                        } catch {
                            reject("Error", error.localizedDescription, nil)
                        }

                    }
                            }
//
            
        } else if map["devicesIds"] != nil && map["startTime"] != nil && map["endTime"] != nil {
            let mDeviceIds = map["devicesIds"] as! [Int]
            let mStartTime = map["startTime"] as! Double
            let mEndTime = map["endTime"] as! Double
            
            
            IntouchApis.shared.getGeoFenceActivity(devicesIds:mDeviceIds, startTime: mStartTime, endTime: mEndTime) { (response, error) in
                if let error = error {
                    reject("Error", error.localizedDescription, nil)
                        }
                    if let result = response
                      {
                        do {
                            let encodedData = try JSONEncoder().encode(result)
                            let jsonString = String(data: encodedData,encoding: .utf8)
                            let nsDict = self.convertStringToDictionary(text: jsonString!,rejecter: reject)
                            resolve(nsDict!)
                        } catch {
                            reject("Error", error.localizedDescription, nil)
                        }

                    }
                            }
            
            
        } else {
            
            reject("GeoFenceActivity Error ", "Please provide required params", nil)
            
        }
        
    }
    
    @objc func createTrip(_ map:NSDictionary,reslover resolve: @escaping RCTPromiseResolveBlock,rejecter reject: @escaping RCTPromiseRejectBlock ) -> Void {
        
        
        
        if map["tripName"] != nil && map["deviceId"] != nil && map["scheduleEndTime"] != nil && map["metaData"] != nil && map["tripDestination"] != nil && map["tripGeofences"] != nil && map["isForceCloseEnable"] != nil  {

            let mTripName = map["tripName"] as! String
            let mDeviceId = map["deviceId"] as! Int
            let  mScheduleEndTime = map["scheduleEndTime"] as! NSNumber
            let dictMetaData = map["metaData"] as! NSDictionary
            let mMetaData = createMetaData(dict:dictMetaData)
            let  mIsForceCloseEnable = map["isForceCloseEnable"] as! Bool
            let mTripGeofenceArray = map["tripGeofences"] as! NSArray
            let mTripGeofenceList = createTripGeofenceList(tripGeofenceList: mTripGeofenceArray)

            let mtripDestinationDict = map["tripDestination"] as! NSDictionary
            let mTripDestination = createTripDestination(dict: mtripDestinationDict)


            let options = IntouchCreateTripOptions(name:mTripName, geofence:mTripGeofenceList, tripDestination: mTripDestination, deviceId: mDeviceId, forceClose: mIsForceCloseEnable, scheduledEndTime: Double(truncating: mScheduleEndTime), metaData: mMetaData)
                            IntouchApis.shared.createTripData(optons: options) { (response, error) in
                                if let error = error {
                                    reject("Error", error.localizedDescription, nil)
                                        }
                                    if let result = response
                                      {
                                        do {
                                            let encodedData = try JSONEncoder().encode(result)
                                            let jsonString = String(data: encodedData,encoding: .utf8)
                                            let nsDict = self.convertStringToDictionary(text: jsonString!,rejecter: reject)
                                            resolve(nsDict!)
                                        } catch {
                                            reject("Error", error.localizedDescription, nil)
                                        }

                                    }

                            }

        } else if map["tripName"] != nil && map["deviceId"] != nil && map["metaData"] != nil && map["tripDestination"] != nil && map["tripGeofences"] != nil && map["isForceCloseEnable"] != nil  {

            let mTripName = map["tripName"] as! String
            let mDeviceId = map["deviceId"] as! Int
            let dictMetaData = map["metaData"] as! NSDictionary
            let mMetaData = createMetaData(dict:dictMetaData)
            let  mIsForceCloseEnable = map["isForceCloseEnable"] as! Bool
            let mTripGeofenceArray = map["tripGeofences"] as! NSArray
            let mTripGeofenceList = createTripGeofenceList(tripGeofenceList: mTripGeofenceArray)

            let mtripDestinationDict = map["tripDestination"] as! NSDictionary
            let mTripDestination = createTripDestination(dict: mtripDestinationDict)


            let options = IntouchCreateTripOptions(name: mTripName, geofences: mTripGeofenceList, tripDestination: mTripDestination, deviceId: mDeviceId, forceClose: mIsForceCloseEnable, metaData: mMetaData)
                            IntouchApis.shared.createTripData(optons: options) { (response, error) in
                                if let error = error {
                                    reject("Error", error.localizedDescription, nil)
                                        }
                                    if let result = response
                                      {
                                        do {
                                            let encodedData = try JSONEncoder().encode(result)
                                            let jsonString = String(data: encodedData,encoding: .utf8)
                                            let nsDict = self.convertStringToDictionary(text: jsonString!,rejecter: reject)
                                            resolve(nsDict!)
                                        } catch {
                                            reject("Error", error.localizedDescription, nil)
                                        }

                                    }

                            }

        } else if map["tripName"] != nil && map["deviceId"] != nil && map["metaData"] != nil && map["isForceCloseEnable"] != nil  {

            let mTripName = map["tripName"] as! String
            let mDeviceId = map["deviceId"] as! Int
            let dictMetaData = map["metaData"] as! NSDictionary
            let mMetaData = createMetaData(dict:dictMetaData)
            let  mIsForceCloseEnable = map["isForceCloseEnable"] as! Bool


            let options = IntouchCreateTripOptions(name: mTripName, deviceId: mDeviceId, forceClose: mIsForceCloseEnable, metaData: mMetaData)
                            IntouchApis.shared.createTripData(optons: options) { (response, error) in
                                if let error = error {
                                    reject("Error", error.localizedDescription, nil)
                                        }
                                    if let result = response
                                      {
                                        do {
                                            let encodedData = try JSONEncoder().encode(result)
                                            let jsonString = String(data: encodedData,encoding: .utf8)
                                            let nsDict = self.convertStringToDictionary(text: jsonString!,rejecter: reject)
                                            resolve(nsDict!)
                                        } catch {
                                            reject("Error", error.localizedDescription, nil)
                                        }

                                    }

                            }
//
        } else {

            reject("createTrip Error ", "Please provide required params", nil)

        }
//
        
        
    }
    
    
    @objc func getTrips(_ map:NSDictionary,reslover resolve: @escaping RCTPromiseResolveBlock,rejecter reject: @escaping RCTPromiseRejectBlock ) -> Void {

        if map["deviceIds"] != nil && map["limit"] != nil && map["status"] != nil && map["statTimeStamp"] != nil && map["endTimeStamp"] != nil {
            let mDeviceIds = map["deviceIds"] as! [Int]
            let mLimit = map["limit"] as! Int
            let  mStatus = map["status"] as! Int
            let mStatTimeStamp = map["statTimeStamp"] as! Double
            let mEndTimeStamp = map["endTimeStamp"] as! Double
            
            let options = IntouchGetAllTripsOptions(deviceIds: mDeviceIds, startTime: mStatTimeStamp, endTime: mEndTimeStamp, limit: mLimit, status: mStatus)
                            IntouchApis.shared.getTrips(options: options) { (tripResponse, error) in
                                if let error = error {
                                    reject("Error", error.localizedDescription, nil)
                                        }
                                    if let result = tripResponse
                                      {
                                        do {
                                            let encodedData = try JSONEncoder().encode(result)
                                            let jsonString = String(data: encodedData,encoding: .utf8)
                                            let nsDict = self.convertStringToDictionary(text: jsonString!,rejecter: reject)
                                            resolve(nsDict!)
                                        } catch {
                                            reject("Error", error.localizedDescription, nil)
                                        }

                                    }
                            }
//
            
        } else if map["limit"] != nil && map["status"] != nil && map["statTimeStamp"] != nil && map["endTimeStamp"] != nil {
            let mLimit = map["limit"] as! Int
            let  mStatus = map["status"] as! Int
            let mStatTimeStamp = map["statTimeStamp"] as! Double
            let mEndTimeStamp = map["endTimeStamp"] as! Double
            
            let options = IntouchGetAllTripsOptions(deviceIds: [], startTime: mStatTimeStamp, endTime: mEndTimeStamp, limit: mLimit, status: mStatus)
                            IntouchApis.shared.getTrips(options: options) { (tripResponse, error) in
                                if let error = error {
                                    reject("Error", error.localizedDescription, nil)
                                        }
                                    if let result = tripResponse
                                      {
                                        do {
                                            let encodedData = try JSONEncoder().encode(result)
                                            let jsonString = String(data: encodedData,encoding: .utf8)
                                            let nsDict = self.convertStringToDictionary(text: jsonString!,rejecter: reject)
                                            resolve(nsDict!)
                                        } catch {
                                            reject("Error", error.localizedDescription, nil)
                                        }

                                    }
                            }
            
            
        }else {
            
            IntouchApis.shared.getTrips { (response, error) in
                if let error = error {
                    reject("Error", error.localizedDescription, nil)
                        }
                    if let result = response
                      {
                        do {
                            let encodedData = try JSONEncoder().encode(result)
                            let jsonString = String(data: encodedData,encoding: .utf8)
                            let nsDict = self.convertStringToDictionary(text: jsonString!,rejecter: reject)
                            resolve(nsDict!)
                        } catch {
                            reject("Error", error.localizedDescription, nil)
                        }

                    }
                }
        }
        
    }
    
    
    @objc func getTripInfo(_ map:NSDictionary,reslover resolve: @escaping RCTPromiseResolveBlock,rejecter reject: @escaping RCTPromiseRejectBlock ) -> Void {
        
        if map["tripId"] != nil && map["isPositionEventsEnable"] != nil && map["isLocationEnable"] != nil && map["isPolylineEnable"] != nil  {
            let tripId = map["tripId"] as! String
            let isPositionEventsEnable = map["isPositionEventsEnable"] as! Bool
            let isLocationEnable = map["isLocationEnable"] as! Bool
            let isPolylineEnable = map["isPolylineEnable"] as! Bool
            
            IntouchApis.shared.getTripInfo(tripId: tripId, isEventsEnable: isPositionEventsEnable, isLocationEnable: isLocationEnable, isPolylineEnable: isPolylineEnable) { (response, error) in
                if let error = error {
                    reject("Error", error.localizedDescription, nil)
                        }
                    if let result = response
                      {
                        do {
                            let encodedData = try JSONEncoder().encode(result)
                            let jsonString = String(data: encodedData,encoding: .utf8)
                            let nsDict = self.convertStringToDictionary(text: jsonString!,rejecter: reject)
                            resolve(nsDict!)
                        } catch {
                            reject("Error", error.localizedDescription, nil)
                        }

                    }
            }
            
        } else  if map["tripId"] != nil  {
            let tripId = map["tripId"] as! String
            
            IntouchApis.shared.getTripInfo(tripId: tripId) { (response, error) in
                if let error = error {
                    reject("Error", error.localizedDescription, nil)
                        }
                    if let result = response
                      {
                        do {
                            let encodedData = try JSONEncoder().encode(result)
                            let jsonString = String(data: encodedData,encoding: .utf8)
                            let nsDict = self.convertStringToDictionary(text: jsonString!,rejecter: reject)
                            resolve(nsDict!)
                        } catch {
                            reject("Error", error.localizedDescription, nil)
                        }

                    }
            }
//
        } else {
            
            reject("getTripInfo Error ", "Please provide required params", nil)
        }
        
    }
    
    @objc func closeTrip(_ map:NSDictionary,reslover resolve: @escaping RCTPromiseResolveBlock,rejecter reject: @escaping RCTPromiseRejectBlock ) -> Void {
        
        if map["tripId"] != nil {
            let tripId = map["tripId"] as! String
            IntouchApis.shared.closeTrip(tripId: tripId) { (status, error) in
                if let error = error {
                   reject("Error", error.localizedDescription, nil)
                } else {
                    resolve("success")
                }
                            }
        }else {
            
            reject("closeTripInfo Error ", "Please provide required params", nil)
        }
        
    }
    
    //Getting error while success
    @objc func createAlarm(_ map:NSDictionary,reslover resolve: @escaping RCTPromiseResolveBlock,rejecter reject: @escaping RCTPromiseRejectBlock ) -> Void {
        
        if map["alarmParameters"] != nil {
             let alarmParameters = map["alarmParameters"] as! NSDictionary
              let options = createAlarmOptions(alarmParameters: alarmParameters)
            if options != nil {
                IntouchApis.shared.getAlarmCreated(alarmParam: options!) { (response, error) in
                    if let error = error {
                        reject("Error", error.localizedDescription, nil)
                            }
                        if let result = response
                          {
                            do {
                                let encodedData = try JSONEncoder().encode(result)
                                let jsonString = String(data: encodedData,encoding: .utf8)
                                let nsDict = self.convertStringToDictionary(text: jsonString!,rejecter: reject)
                                resolve(nsDict!)
                            } catch {
                                reject("Error", error.localizedDescription, nil)
                            }

                        }
                    }
            }else{
                reject("CreateAlarm Error ", "Please provide required alarms params", nil)
            }

        } else {
            reject("CreateAlarm Error ", "Please provide required params", nil)

        }

    }
    
    @objc func getAlarmConfigs(_ map:NSDictionary,reslover resolve: @escaping RCTPromiseResolveBlock,rejecter reject: @escaping RCTPromiseRejectBlock ) -> Void {

        if map["alarmIds"] != nil && map["deviceIds"] != nil && map["alarmTypes"] != nil   {
            let mAlarmIds = map["alarmIds"] as! [Int]
            let mDeviceIds = map["deviceIds"] as! [Int]
            let mAlarmTypes = map["alarmTypes"] as! [Int]
            

            IntouchApis.shared.getAlarmConfig(alarmIds:mAlarmIds, deviceIds:mDeviceIds, alarmTypes:mAlarmTypes) { (response, error) in
                if let error = error {
                    reject("Error", error.localizedDescription, nil)
                        }
                    if let result = response
                      {
                        do {
                            let encodedData = try JSONEncoder().encode(result)
                            let jsonString = String(data: encodedData,encoding: .utf8)
                            let nsDict = self.convertStringToDictionary(text: jsonString!,rejecter: reject)
                            resolve(nsDict!)
                        } catch {
                            reject("Error", error.localizedDescription, nil)
                        }

                    }
              }
            
            
        }else{
            
            IntouchApis.shared.getAlarmConfig { (response, error) in
                if let error = error {
                    reject("Error", error.localizedDescription, nil)
                        }
                    if let result = response
                      {
                        do {
                            let encodedData = try JSONEncoder().encode(result)
                            let jsonString = String(data: encodedData,encoding: .utf8)
                            let nsDict = self.convertStringToDictionary(text: jsonString!,rejecter: reject)
                            resolve(nsDict!)
                        } catch {
                            reject("Error", error.localizedDescription, nil)
                        }

                    }
               }
        }
        
    }
    
    @objc func updateAlarm(_ map:NSDictionary,reslover resolve: @escaping RCTPromiseResolveBlock,rejecter reject: @escaping RCTPromiseRejectBlock ) -> Void {
        
        if map["alarmId"] != nil && map["alarmParameters"] != nil {
            let mAlarmId = map["alarmId"] as! Int
            let alarmParameters = map["alarmParameters"] as! NSDictionary

            let options = createAlarmOptions(alarmParameters: alarmParameters)
            if options != nil {
                IntouchApis.shared.updateAlarm(alarmId: mAlarmId, param: options!) { (status, error) in
                   if let error = error {
                      reject("Error", error.localizedDescription, nil)
                   } else {
                    resolve("success")
                   }

                     }
            }else{
                reject("Update Alram Error", "Please provide all required alarm  parameters.", nil)
            }

        } else {

            reject("Update Alram Error", "Please provide all required parameters.", nil)
        }
        
    }
    
    @objc func deleteAlarm(_ map:NSDictionary,reslover resolve: @escaping RCTPromiseResolveBlock,rejecter reject: @escaping RCTPromiseRejectBlock ) -> Void {
        
        if map["alarmIds"] != nil {
            let mAlarmIds = map["alarmIds"] as! [Int]
//
            IntouchApis.shared.DeleteAlarms(alarmIds:mAlarmIds) { (statusCode, error) in
                if let error = error {
                   reject("Error", error.localizedDescription, nil)
                } else {
                    resolve("success")
                }

                            }
            
        } else  if map["alarmId"] != nil {
            let mAlarmId = map["alarmId"] as! Int
            
            IntouchApis.shared.DeleteAlarm(alarmId: mAlarmId) { (statusCode, error) in
                if let error = error {
                   reject("Error", error.localizedDescription, nil)
                } else {
                    resolve("success")
                }                               }
//
        } else {
            reject("deleteAlarm Error ", "Please provide required params", nil)
        }
        
    }
    
    
    @objc func getAlarmsLogs(_ map:NSDictionary,reslover resolve: @escaping RCTPromiseResolveBlock,rejecter reject: @escaping RCTPromiseRejectBlock ) -> Void {
        
        
        if map["deviceIds"] != nil && map["alarmTypes"] != nil && map["endTime"] != nil && map["startTime"] != nil  {
            let mDeviceIds = map["deviceIds"] as! [Int]
            let mAlarmTypes = map["alarmTypes"] as! [Int]
            let mStartTime = map["startTime"] as! Double
            let mEndTime = map["endTime"] as! Double

            IntouchApis.shared.getAlarmLogs(deviceId:mDeviceIds, alarmId:mAlarmTypes, startTime: mStartTime, endTime: mEndTime) { (response, error) in  if let error = error {
                reject("Error", error.localizedDescription, nil)
                    }
                if let result = response
                  {
                    do {
                        let encodedData = try JSONEncoder().encode(result)
                        let jsonString = String(data: encodedData,encoding: .utf8)
                        let nsDict = self.convertStringToDictionary(text: jsonString!,rejecter: reject)
                        resolve(nsDict!)
                    } catch {
                        reject("Error", error.localizedDescription, nil)
                    }

                }
                           }

        } else if map["endTime"] != nil && map["startTime"] != nil  {
            let mStartTime = map["startTime"] as! Double
            let mEndTime = map["endTime"] as! Double

            IntouchApis.shared.getAlarmLogs(startTime: mStartTime, endTime: mEndTime) { (response, error) in  if let error = error {
                reject("Error", error.localizedDescription, nil)
                    }
                if let result = response
                  {
                    do {
                        let encodedData = try JSONEncoder().encode(result)
                        let jsonString = String(data: encodedData,encoding: .utf8)
                        let nsDict = self.convertStringToDictionary(text: jsonString!,rejecter: reject)
                        resolve(nsDict!)
                    } catch {
                        reject("Error", error.localizedDescription, nil)
                    }

                }
                           }

        } else {
            reject("getAlarmConfig Error ", "Please provide required params", nil)

        }
        
    }
    
   
    func createTripDestination(dict:NSDictionary) -> IntouchTripDestination {


            let metaData = dict["metaData"] as! NSDictionary
            let scheduledAt = dict["scheduledAt"] as! Double
            let radius = dict["radius"] as! Double
            let geometry = dict["geometry"] as! NSDictionary

             let mCoordinates = geometry["coordinates"] as! NSArray

            var options:IntouchGeometryBase
            if mCoordinates.count == 1 {
            let mPoint = mCoordinates.firstObject as! NSArray
            let lat = mPoint[1] as! Double
            let lng = mPoint[0] as! Double
            options =  IntouchGeometryPoint(point: CLLocation(latitude: lat, longitude: lng))
        }else {
            let coordinates = createCLLocationArray(points: mCoordinates)
            options = IntouchGeometryPolygon(points: coordinates)
        }

            return IntouchTripDestination(geoemtry: options, radius: radius, scheduledAt: scheduledAt, metadata: createMetaData(dict: metaData))

    }

    func createMetaData(dict:NSDictionary) -> [String:String] {
        let metaData = NSMutableDictionary()

        for (key, value) in dict {
            metaData[key as! String] = "\(value)"
            }
        return metaData as! [String : String]
    }
//
//    //convert jsonString into a dictionary
    func convertStringToDictionary(text: String,rejecter reject: @escaping RCTPromiseRejectBlock ) -> [String:AnyObject]? {
        if let data = text.data(using: .utf8) {
            do {
                let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String:AnyObject]
                return json
            } catch {
                reject("Parsing error",error.localizedDescription,nil)
            }
        }
        return nil
    }

    func createAlarmOptions(alarmParameters:NSDictionary) -> IntouchAlarmOptions? {

        if alarmParameters["alarmType"] != nil && alarmParameters["deviceId"] != nil && alarmParameters["type"] != nil &&  alarmParameters["duration"] != nil &&
            alarmParameters["limit"] != nil &&
            alarmParameters["geofenceId"] != nil{

            let alarmType = alarmParameters["alarmType"] as! Int
            let deviceIds = alarmParameters["deviceId"] as! [Int]
            let type = alarmParameters["type"] as! Int
            let duration = alarmParameters["duration"] as! Int
            let limit = alarmParameters["limit"] as! Int
            let geofenceIds = alarmParameters["geofenceId"] as! [Int]

           return IntouchAlarmOptions(alarmType: alarmType, deviceIds:deviceIds, type: type, duration: duration, limit: limit, geofenceIds:geofenceIds, severity: 0)
        }
        return nil
    }

    // convert nsArray into CLLOCATION array
    func createCLLocationArray(points:NSArray) -> [CLLocation] {
        var locations :[CLLocation] = []


        for point  in points {
            let location = point as! NSArray
            let lat = location[1] as! Double
            let lng = location[0] as! Double

            locations.append(CLLocation(latitude:lat, longitude:lng))
        }

        return locations
    }

    func createTripGeofenceList(tripGeofenceList:NSArray) -> [IntouchTripsGeofences] {
        var list :[IntouchTripsGeofences] = []

        for tripGeofence in tripGeofenceList {

            let map = tripGeofence as! NSDictionary
            let mRadius = map["radius"] as! Double
            let mScheduledAt = map["scheduledAt"] as! Double
            let mMetaDataDict = map["metaData"] as! NSDictionary
            let mMetaData = createMetaData(dict: mMetaDataDict)

            let geometryMap = map["geometry"] as! NSDictionary
            let mCoordinates = geometryMap["coordinates"] as! NSArray

            var options:IntouchGeometryBase
            if mCoordinates.count == 1 {
                let mPoint = mCoordinates.firstObject as! NSArray
                let lat = mPoint[0] as! Double
                let lng = mPoint[1] as! Double
                options =  IntouchGeometryPoint(point: CLLocation(latitude: lat, longitude: lng))
            }else {
                let coordinates = createCLLocationArray(points: mCoordinates)
                options = IntouchGeometryPolygon(points: coordinates)
            }


            list.append(IntouchTripsGeofences(geoemtry: options, radius: mRadius, scheduledAt: mScheduledAt, metadata: mMetaData))
        }
        return list
    }
}
