import BluxClient

@objc(Blux)
class Blux: RCTEventEmitter {
    
    var NOTIFICATION_CLICKED_EVENT_KEY: String="notification-clicked"
    var NOTIFICATION_FORGROUND_RECEIVED_EVENT_KEY: String="notification-foreground-received"
    
     @objc(initialize:withBluxSecretKey:withRequestPermissionOnLaunch:withResolver:withRejecter:)
     func initialize(bluxClientId: String,  bluxSecretKey: String, requestPermissionOnLaunch: Bool, resolver resolve: RCTPromiseResolveBlock, rejecter reject: RCTPromiseRejectBlock) {
         DispatchQueue.main.async {
             let launchOptions = self.bridge.launchOptions as? [UIApplication.LaunchOptionsKey: Any]
             BluxClient.initialize(launchOptions, bluxClientId:bluxClientId, bluxSecretKey:bluxSecretKey, requestPermissionOnLaunch: requestPermissionOnLaunch)
         }
         resolve(nil)
     }
    
    func convertLogLevelToEnum(level: String)-> LogLevel? {
        switch level.lowercased() {
        case "error":
            return LogLevel.error
        case "verbose":
            return LogLevel.verbose
        default:
            return nil
        }
    }
    
    @objc(setLogLevel:withResolver:withRejecter:)
    func setLogLevel(level: String, resolver resolve: RCTPromiseResolveBlock, rejecter reject: RCTPromiseRejectBlock) {
        let levelAsEnum = self.convertLogLevelToEnum(level:level);
        if let validLevel = levelAsEnum {
            BluxClient.setLogLevel(level: validLevel)
            resolve(nil)
        } else {
            reject("INVALID_LOG_LEVEL", "Invalid log level: \(level)", NSError(domain: "", code: 400, userInfo: [NSLocalizedDescriptionKey: "Invalid log level: \(level)"]))
        }
    }
    
    
    @objc(setUserId:withResolver:withRejecter:)
    func setUserId(userId: String?, resolver resolve: RCTPromiseResolveBlock, rejecter reject: RCTPromiseRejectBlock) {
        BluxClient.setUserId(userId:userId)
        resolve(nil)
    }
    
    @objc(sendRequest:withResolver:withRejecter:)
    func sendRequest(events: NSArray, resolver resolve: RCTPromiseResolveBlock, rejecter reject: RCTPromiseRejectBlock) {
        let eventsCodable = events.compactMap { dict -> Event? in
            guard let dict = dict as? NSDictionary,
                  let eventType = dict["event_type"] as? String,
                  let timestamp = dict["timestamp"] as? Double else {
                return nil
            }
            return try? Event(eventType: eventType)
                .setItemId(dict["item_id"] as? String)
                .setTimestamp(timestamp)
                .setEventValue(dict["event_value"] as? String)
                .setFrom(dict["from"] as? String)
                .setUrl(dict["url"] as? String)
                .setRef(dict["ref"] as? String)
                .setRecommendationId(dict["recommendation_id"] as? String)
                .setEventProperties(dict["event_properties"] as? [String: String])
                .setUserProperties(dict["user_properties"] as? [String: String])
        }
        BluxClient.sendRequestData(eventsCodable)
        resolve(nil)
    }
    
    @objc func startSendEventNotificationClicked() {
        BluxClient.setNotificationClickedHandler() { notification in
            self.sendEvent(withName: self.NOTIFICATION_CLICKED_EVENT_KEY, body: notification.toDictionary())
        }
    }
    
    @objc func startSendEventNotificationForegroundReceived() {
        BluxClient.setNotificationForegroundReceivedHandler() { event in
            self.sendEvent(withName: self.NOTIFICATION_FORGROUND_RECEIVED_EVENT_KEY, body: event.notification.toDictionary())
        }
    }
    
    override open func supportedEvents() -> [String] {
        return [self.NOTIFICATION_CLICKED_EVENT_KEY, self.NOTIFICATION_FORGROUND_RECEIVED_EVENT_KEY]
    }
}
