/*
 * Copyright © Dynamsoft Corporation. All rights reserved.
 */

import Foundation
import React
import DynamsoftCaptureVisionBundle

extension CrossVerificationCriteria {
    static func create(fromJson dic: [AnyHashable: Any]) -> CrossVerificationCriteria {
        let criteria = CrossVerificationCriteria()
        if let frameWindow = dic["frameWindow"] as? NSNumber {
            criteria.frameWindow = frameWindow.intValue
        }
        if let minConsistentFrames = dic["minConsistentFrames"] as? NSNumber {
            criteria.minConsistentFrames = minConsistentFrames.intValue
        }
        return criteria
    }

    func toJson() -> [String: Any] {
        return ["frameWindow": frameWindow, "minConsistentFrames": minConsistentFrames]
    }
}

@objc(RNDynamsoftMultiCrossFilter)
class RNDynamsoftMultiCrossFilter: RCTEventEmitter {

    @objc(createInstance)
    func createInstance() -> String {
        let filter = MultiFrameResultCrossFilter()
        let key = String(filter.hash)
        DSFilterStore.shared.map[key] = filter
        return key
    }

    @objc func destroy(_ key: String) {
        DSFilterStore.shared.map.removeValue(forKey: key)
    }

    @objc func enableResultCrossVerification(_ key: String, type: NSInteger, isEnabled: Bool) {
        DSFilterStore.shared.map[key]?.enableResultCrossVerification(CapturedResultItemType(rawValue: UInt(type)), isEnabled: isEnabled)
    }

    @objc(isResultCrossVerificationEnabled:type:resolve:reject:)
    func isResultCrossVerificationEnabled(_ key: String, type: NSInteger,
                                                 resolve: @escaping RCTPromiseResolveBlock,
                                                 reject: @escaping RCTPromiseRejectBlock) {
        resolve(DSFilterStore.shared.map[key]?.isResultCrossVerificationEnabled(CapturedResultItemType(rawValue: UInt(type))) ?? false)
    }

    @objc func enableResultDeduplication(_ key: String, type: NSInteger, isEnabled: Bool) {
        DSFilterStore.shared.map[key]?.enableResultDeduplication(CapturedResultItemType(rawValue: UInt(type)), isEnabled: isEnabled)
    }

    @objc(isResultDeduplicationEnabled:type:resolve:reject:)
    func isResultDeduplicationEnabled(_ key: String, type: NSInteger,
                                             resolve: @escaping RCTPromiseResolveBlock,
                                             reject: @escaping RCTPromiseRejectBlock) {
        resolve(DSFilterStore.shared.map[key]?.isResultDeduplicationEnabled(CapturedResultItemType(rawValue: UInt(type))) ?? false)
    }

    @objc func setDuplicateForgetTime(_ key: String, type: NSInteger, time: NSInteger) {
        DSFilterStore.shared.map[key]?.setDuplicateForgetTime(CapturedResultItemType(rawValue: UInt(type)), duplicateForgetTime: time)
    }

    @objc(getDuplicateForgetTime:type:resolve:reject:)
    func getDuplicateForgetTime(_ key: String, type: NSInteger,
                                       resolve: @escaping RCTPromiseResolveBlock,
                                       reject: @escaping RCTPromiseRejectBlock) {
        resolve(DSFilterStore.shared.map[key]?.getDuplicateForgetTime(CapturedResultItemType(rawValue: UInt(type))) ?? 0)
    }

    @objc func enableLatestOverlapping(_ key: String, type: NSInteger, isEnabled: Bool) {
        DSFilterStore.shared.map[key]?.enableLatestOverlapping(CapturedResultItemType(rawValue: UInt(type)), isEnabled: isEnabled)
    }

    @objc(isLatestOverlappingEnabled:type:resolve:reject:)
    func isLatestOverlappingEnabled(_ key: String, type: NSInteger,
                                           resolve: @escaping RCTPromiseResolveBlock,
                                           reject: @escaping RCTPromiseRejectBlock) {
        resolve(DSFilterStore.shared.map[key]?.isLatestOverlappingEnabled(CapturedResultItemType(rawValue: UInt(type))) ?? false)
    }

    @objc func setMaxOverlappingFrames(_ key: String, type: NSInteger, maxOverlappingFrames: NSInteger) {
        DSFilterStore.shared.map[key]?.setMaxOverlappingFrames(CapturedResultItemType(rawValue: UInt(type)), maxOverlappingFrames: maxOverlappingFrames)
    }

    @objc(getMaxOverlappingFrames:type:resolve:reject:)
    func getMaxOverlappingFrames(_ key: String, type: NSInteger,
                                        resolve: @escaping RCTPromiseResolveBlock,
                                        reject: @escaping RCTPromiseRejectBlock) {
        resolve(DSFilterStore.shared.map[key]?.getMaxOverlappingFrames(CapturedResultItemType(rawValue: UInt(type))) ?? 0)
    }

    @objc func setResultCrossVerificationCriteria(_ key: String, type: NSInteger, criteria: [AnyHashable: Any]) {
        let c = CrossVerificationCriteria.create(fromJson: criteria)
        DSFilterStore.shared.map[key]?.setResultCrossVerificationCriteria(c, resultItemTypes: CapturedResultItemType(rawValue: UInt(type)))
    }

    @objc(getResultCrossVerificationCriteria:type:resolve:reject:)
    func getResultCrossVerificationCriteria(_ key: String, type: NSInteger,
                                                   resolve: @escaping RCTPromiseResolveBlock,
                                                   reject: @escaping RCTPromiseRejectBlock) {
        resolve(DSFilterStore.shared.map[key]?.getResultCrossVerificationCriteria(CapturedResultItemType(rawValue: UInt(type))).toJson())
    }
}
