import UnityAds
import AppTrackingTransparency
import AdSupport

let TEST_GAME_ID = "1737958"; // for arPlacement test use game id: 1767349
let TEST_VIDEO_AD_PLACEMENT_ID = "video";
let TEST_REWARDED_VIDEO_AD_PLACEMENT_ID = "rewardedVideo";
let TEST_BANNER_AD_PLACEMENT_ID = "Banner";

//AR ADS TEST IDS
let TEST_AR_GAME_ID = ""
let TEST_AR_AD_PLACEMENT_ID = "arPlacement"
var IDFA_ALLOWED = false

public class LastState {
    var LAST_STATUS: String? = "NOT_LOADED"
    var LAST_ERROR:  String? = "";
    public static let shared = LastState()
}

@objc(UnityAds3)
class UnityAds3: CDVPlugin, UnityAdsLoadDelegate{

    
    var bannerAdsDelegate: UADSBannerAds?
    var videoAdsDelegate: UnityVideoAds?
    var uaLoadDeleage: UnityAdsLoadDelegate?

    override init() {}
    
    @objc(UnityAdsInit:)
    func UnityAdsInit(command: CDVInvokedUrlCommand) {
        
        let promise = CommandPromise(id: command.callbackId, comDelegate: self.commandDelegate)
        
        if #available(iOS 14, *) {
            ATTrackingManager.requestTrackingAuthorization { status in
                switch status {
                    case .authorized:
                        print("IDFA CURRENT STATUS: Authorized", ASIdentifierManager.shared().advertisingIdentifier)
                        self.allowedToInit(command:command, promise: promise, idfa: "AUTHORIZED")
                    case .denied:
                        print("IDFA CURRENT STATUS: Denied")
                        self.allowedToInit(command:command, promise: promise, idfa: "DENIED")
                    case .notDetermined:
                        // Tracking authorization dialog has not been shown
                        print("IDFA CURRENT STATUS: Not Determined")
                        self.allowedToInit(command:command, promise: promise, idfa: "NOT_DETERMIDED")
                    case .restricted:
                        print("IDFA CURRENT STATUS: Restricted")
                        self.allowedToInit(command:command, promise: promise, idfa: "RESTRICTED")
                    @unknown default:
                        print("IDFA CURRENT STATUS: Unknown")
                        self.allowedToInit(command:command, promise: promise, idfa: "UNKNOWN")
                }

            }
        }
        else{
            allowedToInit(command:command, promise: promise)
        }
        
    }
    
    
    func allowedToInit(command: CDVInvokedUrlCommand, promise: CommandPromise, idfa: String? = "NOT_NEEDED"){
        
        var gameId  = command.arguments[0] as? String ?? ""
        let isTest  = command.arguments[1] as? Bool ?? false
        let isDebug = command.arguments[2] as? Bool ?? false
        let privacyMode = command.arguments[3] as? String ?? "none"

        
        
        if gameId == "" {
            promise.reject(msg: "GameID not specified", keep: true)
            return
        }

        if gameId == "TEST" {
            gameId = TEST_GAME_ID
        }

           //SET PRIVACY MODE BEFORE INITIALIZE
        if( privacyMode != "none" ){
            
            //app: This app is directed at children; no users will receive personalized ads.
            let privModemetaData = UADSMetaData()
            privModemetaData.set("privacy.mode", value: privacyMode )
            privModemetaData.commit()


             // mixed: This user will NOT receive personalized ads.
            if( privacyMode == "mixed" ){
                let userNonBehvmetaData = UADSMetaData()
                userNonBehvmetaData.set("user.nonbehavioral", value: NSNumber(value: true ))
                userNonBehvmetaData.commit()
            }
        }

        
        promise.resolve(msg: String(format: "[\"%@\",\"%@\"]", "UNITYADS", "IDFA_" + idfa!) , keep: true)
        
        if UnityAds.isInitialized() {
            promise.reject(msg: "UnityAds already initialized", keep: true)
            return
        }
        
        promise.resolve(msg: String(format: "[\"%@\",\"%@\"]", "UNITYADS", "INITIALIZING") , keep: true)
        
        //UnityAds Initialize
        self.videoAdsDelegate  = UnityVideoAds(gameID: gameId, testMode: isTest, isDebug: isDebug, prom: promise)
        
        promise.resolve(msg: String(format: "[\"%@\",\"%@\"]", "UNITYADS", "IS_READY") , keep: true)
        
        self.bannerAdsDelegate = UADSBannerAds(prom:promise)
        debugPrint("[UnityAds3][bannerAdsDelegate]", self.bannerAdsDelegate?.promise?.callback as Any)
    }
    
    
    @objc(GetPlacementState:)
    func GetPlacementState(command: CDVInvokedUrlCommand){
        
        let promise = CommandPromise(id: command.callbackId, comDelegate: self.commandDelegate)
        var videoAdPlacementId = command.arguments[0] as? String ?? ""

        if videoAdPlacementId == "" {
            promise.reject(msg: "Invalid PlacementID")
           return
        }

        if videoAdPlacementId.uppercased() == "TEST" {
            videoAdPlacementId = TEST_VIDEO_AD_PLACEMENT_ID
        }

        if videoAdPlacementId.uppercased() == "TEST_REWARDED" {
            videoAdPlacementId = TEST_REWARDED_VIDEO_AD_PLACEMENT_ID
        }

        if videoAdPlacementId.uppercased() == "TEST_AR"{
            videoAdPlacementId = TEST_AR_AD_PLACEMENT_ID
        }

        //promise.resolve(msg: "THIS IS AN DEPRECATED METHOD AND WILL BE REMOVE IN THE FUTURE")
        promise.resolve(msg: LastState.shared.LAST_STATUS ?? "EMPTY")
    }



    @objc(ShowVideoAd:)
    func ShowVideoAd(command: CDVInvokedUrlCommand){
        
        debugPrint("[UnityAds3][ShowVideoAd]", command.callbackId as Any)
        
        let promise = CommandPromise(id: command.callbackId , comDelegate: self.commandDelegate)
        
        var videoAdPlacementId = command.arguments[0] as? String ?? ""

        if videoAdPlacementId == "" {
            promise.reject(msg: "Invalid PlacementID" )
            return
        }

        if videoAdPlacementId.uppercased() == "TEST" {
            videoAdPlacementId = TEST_VIDEO_AD_PLACEMENT_ID
        }

        if videoAdPlacementId.uppercased() == "TEST_REWARDED" {
            videoAdPlacementId = TEST_REWARDED_VIDEO_AD_PLACEMENT_ID
        }

        if videoAdPlacementId.uppercased() == "TEST_AR"{
            videoAdPlacementId = TEST_AR_AD_PLACEMENT_ID
        }
        
        self.unityAdsAdLoaded(videoAdPlacementId)

        promise.resolve(msg: String(format: "[\"%@\",\"%@\"]", videoAdPlacementId, "READY") )
        videoAdsDelegate?.show(viewController: self.viewController, placementId: videoAdPlacementId, prom: promise)
    }
    
    func unityAdsAdLoaded(_ placementId: String) {
        debugPrint("[UnityAds3][Banners][unityAdsAdLoaded]")
    }
    
    func unityAdsAdFailed(toLoad placementId: String, withError error: UnityAdsLoadError, withMessage message: String) {
        debugPrint("[UnityAds3][Banners][unityAdsAdFailed]")
    }
    

    @objc(ShowBannerAd:)
    func ShowBannerAd(command: CDVInvokedUrlCommand){
       
        debugPrint("[UnityAds3][ShowBannerAd]", command.callbackId as Any)
        
        let promise = CommandPromise(id: command.callbackId, comDelegate: self.commandDelegate)
        
        var bannerAdPlacementId = command.arguments[0] as? String ?? ""
        let bannerPos = command.arguments[1] as? String ?? ""
        
        if bannerAdPlacementId == "" {
            promise.reject(msg: "Invalid PlacementID" )
            return
        }
        
        if bannerAdPlacementId == "TEST" {
            bannerAdPlacementId = TEST_BANNER_AD_PLACEMENT_ID
        }
        
        bannerAdsDelegate?.showBanner(self.webView, bannerAdPlacementId, bannerPos, promise)
         
    }

    @objc(ManualGdprOpts:)
    func ManualGdprOpts(command: CDVInvokedUrlCommand) {
       
        let promise = CommandPromise(id: command.callbackId, comDelegate: self.commandDelegate)
        
        //debugPrint("[UnityAds3][ManualGdprOpts]", command.arguments)

        let consent  = command.arguments[0] as? Bool ?? false

        let gdprConsentMetaData = UADSMetaData()
        gdprConsentMetaData.set("gdpr.consent", value: NSNumber(value: consent ))
        gdprConsentMetaData.commit()

        promise.resolve(msg: String(format: "[\"%@\",\"%@\"]", "UNITYADS",  consent ? "True" : "False" ) , keep: true)

    }

    @objc(ManualCcpaOpts:)
    func ManualCcpaOpts(command: CDVInvokedUrlCommand) {
       
        let promise = CommandPromise(id: command.callbackId, comDelegate: self.commandDelegate)
        
        //debugPrint("[UnityAds3][ManualCcpaOpts]", command.arguments)

        let consent  = command.arguments[0] as? Bool ?? false

        let privacyConsentMetaData = UADSMetaData()
        privacyConsentMetaData.set("privacy.consent", value: NSNumber(value: consent ))
        privacyConsentMetaData.commit()

        promise.resolve(msg: String(format: "[\"%@\",\"%@\"]", "UNITYADS", consent ? "True" : "False" ) , keep: true)

    }

    @objc(ManualCustomAgeGates:)
    func ManualCustomAgeGates(command: CDVInvokedUrlCommand) {
       
        let promise = CommandPromise(id: command.callbackId, comDelegate: self.commandDelegate)
        
        //debugPrint("[UnityAds3][ManualCustomAgeGates]", command.arguments)

        let useroveragelimit  = command.arguments[0] as? Bool ?? false

        let ageGateMetaData = UADSMetaData()
        ageGateMetaData.set("privacy.useroveragelimit", value: NSNumber(value: useroveragelimit))
        ageGateMetaData.commit()

        promise.resolve(msg: String(format: "[\"%@\",\"%@\"]", "UNITYADS", useroveragelimit ? "True" : "False"  ) , keep: true)

    }

    @objc(GetUnityAdsSdkVersion:)
    func GetUnityAdsSdkVersion(command: CDVInvokedUrlCommand) {
       
        let promise = CommandPromise(id: command.callbackId, comDelegate: self.commandDelegate)

        promise.resolve(msg: String(format: "[\"%@\",\"%@\"]", "UnityAdsSDK", UnityAds.getVersion() ) , keep: true)

    }
        
}
