import React
import BlazeSDK
import BlazeGAM
import GoogleMobileAds

@objc(RTNBlazeGAM)
class BlazeGAMNativeModule: RCTEventEmitter {
    
    var additionalCustomGAMTargetingProperties: [String : String] = [:]
    
    override init() {
        super.init()
    }
    
    override static func moduleName() -> String {
        return "RTNBlazeGAM"
    }
    
    lazy var delegate: BlazeGAMCustomNativeAdsDelegate = .init(
        
        onGAMAdError: { [weak self] error in
            self?.onGAMAdError(error)
        },
        
        onGAMAdEvent: { [weak self] params in
            self?.onGAMAdEvent(eventType: params.eventType,
                               adData: params.adData)
        },
        
        customGAMTargetingProperties: {
            self.customGAMTargetingProperties
        }
        
    )
    
    @objc override static func requiresMainQueueSetup() -> Bool {
        return true
    }
    //------------------- Bridge methods ----------------------//
    
    @objc func enableCustomNativeAds(_ options: [String : AnyHashable],
                                     resolver: @escaping RCTPromiseResolveBlock,
                                     rejecter: @escaping RCTPromiseRejectBlock) {
        guard let options = options.extractEnableCustomNativeAdsOptions() else {
            rejecter("0", "Missing params in options for `enableCustomNativeAds`", nil)
            return
        }
        
        BlazeGAM.shared.enableCustomNativeAds(defaultCustomNativeAdsConfig: options.defaultAdConfig?.toNativeModel,
                                              delegate: delegate)
    }
    
    @objc func disableCustomNativeAds() {
        BlazeGAM.shared.disableCustomNativeAds()
    }
    
    @objc func setCustomGAMTargetingProperties(_ props: [String : AnyHashable],
                                               resolver: @escaping RCTPromiseResolveBlock,
                                               rejecter: @escaping RCTPromiseRejectBlock) {
        guard let props = props as? [String : String] else {
            rejecter("0", "Recived invalid props for `setCustomGAMTargetingProperties`", nil)
            return
        }
                
        additionalCustomGAMTargetingProperties = props
        
        resolver(nil)
    }
    
    override func supportedEvents() -> [String] {
        return SupportedAppEvents.allCases.map({ $0.rawValue })
    }
    
}

extension BlazeGAMNativeModule {
    
    func onGAMAdError(_ error: Error) {
        let event: BlazeGAMEvent = .init(name: "BlazeGAM.onAdError",
                                         body: [
                                            "errorMessage" : error.localizedDescription
                                         ])
        bridge?.sendBlazeGAMEvent(event)
    }

    func onGAMAdEvent(eventType: BlazeGoogleCustomNativeAdsHandlerEventType,
                      adData: BlazeCustomNativeAdData) {
        let event: BlazeGAMEvent = .init(name: "BlazeGAM.onAdEvent",
                                         body: [
                                            "eventType" : eventType.toReactEventTypeParam
                                         ])
        bridge?.sendBlazeGAMEvent(event)
    }
    
    var customGAMTargetingProperties: [String : String] {
        return additionalCustomGAMTargetingProperties
    }
    
}

fileprivate extension BlazeSDK.BlazeGoogleCustomNativeAdsHandlerEventType {
    
    var toReactEventTypeParam: String {
        switch self {

        case .openedAd:
            return "openedAd"

        case .adPageStart:
            return "adPageStart"

        case .adPageFirstQuarter:
            return "adPageFirstQuarter"

        case .adPageThird:
            return "adPageThird"

        case .adPageMid:
            return "adPageMid"

        case .adPageComplete:
            return "adPageComplete"

        case .pausedAdPage:
            return "pausedAdPage"

        case .resumedAdPage:
            return "resumedAdPage"

        case .ctaClicked:
            return "ctaClicked"
        }
    }
    
}
