//
//  BSUNativeAd.swift
//  Unity-iPhone
//
//  Created by Moin Hasan on 5/26/25.
//

import Foundation
import BlueStackSDK
import UIKit

@objc(BSUNativeAd)
public class BSUNativeAd: NSObject, MNGAdsAdapterNativeDelegate, MNGClickDelegate, MNGNativeAdImpressionListener {
    @objc public var nativeAdClient: BSUTypeNativeAdClientRefPointer?
    @objc public var nativeAdsObject: MNGNAtiveObject?
    @objc public var onDidLoadCallback: BSUOnNativeAdDidLoadCallback?
    @objc public var onDidFailCallback: BSUOnNativeAdDidFailCallback?
    @objc public var onRecordImpressionCallback: BSUOnNativeAdDidRecordImpressionCallback?
    @objc public var onPerformClickCallback: BSUOnNativeAdDidPerformClickCallback?
    @objc public var onCloseCallback: BSUOnNativeAdCloseCallback?

    @objc public var title: String?
    @objc public var body: String?
    @objc public var callToAction: String?
    @objc public var badge: String?
    @objc public var iconUrl: String?
    @objc public var coverImageUrl: String?
    @objc public var clickUrl: String?

    private var nativeAdsFactory: MNGAdsSDKFactory?

    @objc public init(nativeAdClientReference: BSUTypeNativeAdClientRefPointer?, placementId: String?) {
        self.nativeAdClient = nativeAdClientReference
        super.init()
        self.nativeAdsFactory = MNGAdsSDKFactory()
        self.nativeAdsFactory?.nativeDelegate = self
        self.nativeAdsFactory?.placementId = placementId
        self.nativeAdsFactory?.clickDelegate = self
        self.nativeAdsFactory?.viewController = BSUPluginUtil.unityGLViewController()
    }

    @objc public func loadAd() {
        nativeAdsFactory?.loadNative()
    }

    @objc public func loadAd(withRequestOptions requestOptionsRef: BSUTypeRequestOptionsRef) {
        let bsuOptions = Unmanaged<BSURequestOptions>.fromOpaque(requestOptionsRef).takeUnretainedValue()
        let sdkOptions = bsuOptions.toSDKRequestOptions()
        
        // RequestOptions to Preference
        var requestOptionsToPreferenceTransformer = RequestOptionsToPreferenceTransformer()
        let preference = requestOptionsToPreferenceTransformer.transform(sdkOptions)
        
        nativeAdsFactory?.loadNative(withPreferences: preference, withCover: false)
    }

    @objc public func recordImpression(_ args: [AnyHashable: Any]) {
        if let nativeAdsObject = self.nativeAdsObject {
            nativeAdsObject.setNativeAdImpressionListener(self)
            nativeAdsObject.recordImpression(args)
        }
    }

    @objc public func performClick(_ args: [AnyHashable: Any]) {
        if let nativeAdsObject = self.nativeAdsObject {
            nativeAdsObject.performClick(args)
        }
    }

    @objc public func destroy() {
        nativeAdsFactory?.releaseMemory()
        nativeAdsFactory = nil
        if let onCloseCallback = self.onCloseCallback {
            onCloseCallback(self.nativeAdClient)
        }
    }

    // MARK: - MNGAdsAdapterNativeDelegate

    public func adsAdapter(_ adsAdapter: MNGAdsAdapter!, nativeObjectDidLoad nativeObject: MNGNAtiveObject!) {
        print("BSUNativeAd: adsAdapter: nativeObjectDidLoad!")
        self.nativeAdsObject = nativeObject
        self.title = nativeObject.title
        self.body = nativeObject.body
        self.badge = "Ad" // nativeObject.badge
        self.callToAction = nativeObject.callToAction
        self.iconUrl = nativeObject.iconUrl
        self.coverImageUrl = nativeObject.coverImageUrl
        // Uncomment if available
        // self.clickUrl = nativeObject.clickUrl //"https://developers.bluestack.app/"
        self.onDidLoadCallback?(self.nativeAdClient)
        
        // (uncomment and implement as needed):
        // nativeObject.updateBadgeTitle("Publicité")
        // let badgeView = nativeObject.badgeView
        // nativeObject.registerView(forInteraction: self.nativeView, withMediaView: self.backgroundImage, withIconImageView: self.iconeImage, withViewController: /* yourViewController */, withClickableView: self.callToActionButton)
    }

    public func adsAdapter(_ adsAdapter: MNGAdsAdapter!, nativeObjectDidFailWithError error: Error!, withCover cover: Bool) {
        print("BSUNativeAd: adsAdapter: nativeObjectDidFailWithError!")
        if let nsError = error as NSError? {
            let errorPointer = Unmanaged.passUnretained(nsError).toOpaque()
            self.onDidFailCallback?(self.nativeAdClient, errorPointer)
        } else {
            self.onDidFailCallback?(self.nativeAdClient, nil)
        }
    }

    // MARK: - MNGClickDelegate

    public func adsAdapterNativeAdWasClicked(_ adsAdapter: MNGAdsAdapter!, nativeObjectClicked clickedAdView: MNGNAtiveObject!) {
        print("BSUNativeAd: MNGClickDelegate: nativeObjectClicked!")
        self.onPerformClickCallback?(self.nativeAdClient)
    }

    // MARK: - MNGNativeAdImpressionListener

    public func onAdImpression() {
        print("BSUNativeAd: MNGNativeAdImpressionListener: onAdImpression!")
        self.onRecordImpressionCallback?(self.nativeAdClient)
    }
}
