//
//  RNYandexAdsMobileBanner.swift
//  react-native-ya-ads-mobile
//
//  Created by Nik Eroon on 29.08.2022.
//

import SwiftUI
import YandexMobileAds
import React


class YaAdNativeView: UIView {
    private var adView: YMANativeBannerView?
    
    var adLoader: YMANativeAdLoader!
    
    @objc var adUnitId: String? {
        didSet {
            setupView()
        }
    }
    @objc var height: NSNumber? {
        didSet {
            setupView()
        }
    }
    @objc var width: NSNumber? {
        didSet {
            setupView()
        }
    }
    
    @objc var onWillLoad: RCTDirectEventBlock?
    @objc var onDidLoad: RCTDirectEventBlock?
    @objc var onClick: RCTBubblingEventBlock?
    @objc var onDidTrackImpression: RCTDirectEventBlock?
    @objc var onWillLeaveApp: RCTDirectEventBlock?
    @objc var onWillPresent: RCTBubblingEventBlock?
    @objc var onDidDismiss: RCTBubblingEventBlock?
    @objc var onClose: RCTBubblingEventBlock?
    @objc var onDidFailLoading: RCTDirectEventBlock?
    @objc var requestParams: NSDictionary?
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupView()
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setupView()
    }
    
    
    
    @objc func setupView () {
        DispatchQueue.main.async {
            guard
                let adUnitID = self.adUnitId,
                let height = self.height,
                let width = self.width
            else { return }
            
            self.adView = YMANativeBannerView()
            self.adView?.frame.size.width = CGFloat(truncating: width)
//            self.adView?.frame = CGRect(x: 0, y: 0, width: CGFloat(truncating: width), height: CGFloat(truncating: height))
            self.adView?.isHidden = true
            
            self.adLoader = YMANativeAdLoader()
            self.adLoader.delegate = self
            
            
            if self.requestParams != nil && self.requestParams is NSDictionary {
                if let requestParams = self.requestParams {
                    let adRewuest = YMAMutableNativeAdRequestConfiguration(adUnitID: adUnitID)
                    var params = ["": ""]
                    
                    var haveInvalidArgument = false
                    for (key, value) in requestParams {
                        if (key is String && value is String) {
                            params[key as! String] = (value as! String)
                        } else {
                            haveInvalidArgument = true
                        }
                    }
                    if (!haveInvalidArgument) {
                        params["preferable-height"] = String(describing: height)
                        params["preferable-width"] = String(describing: width)
                        adRewuest.parameters = params
                        guard let onWillLoad = self.onWillLoad else { return }
                        onWillLoad(["adUnitID": self.adUnitId!])
                        self.adLoader.loadAd(with: adRewuest)
                        return;
                    }
                }
            } else {
                let requestConfiguration = YMAMutableNativeAdRequestConfiguration(adUnitID: adUnitID)
                requestConfiguration.parameters = ["preferable-height": String(describing: height), "preferable-width": String(describing: width)]
                guard let onWillLoad = self.onWillLoad else { return }
                onWillLoad(["adUnitID": self.adUnitId!])
                self.adLoader.loadAd(with: requestConfiguration)
                return;
            }
            
        }
    }
    
    func addAdView() {
        DispatchQueue.main.async {
            guard let adView = self.adView else { return }
            
            adView.translatesAutoresizingMaskIntoConstraints = true
            self.addSubview(adView)
        }}
    
}

// MARK: - YMANativeAdLoaderDelegate

extension YaAdNativeView: YMANativeAdLoaderDelegate {
    func nativeAdLoader(_ loader: YMANativeAdLoader, didLoad ad: YMANativeAd) {
        guard let adView = self.adView else { return }
        ad.delegate = self
        adView.isHidden = false
        
        if (self.width != nil) {
            let heightAd = YMANativeBannerView.height(with: ad, width: CGFloat(truncating: self.width!), appearance: nil)
            adView.frame = CGRect(x: 0, y: 0, width: CGFloat(truncating: self.width!), height: heightAd)
        }
        
        adView.ad = ad
        // TODO
//        adView.frame = CGRect(x: 0, y: 0, width: CGFloat(truncating: self.width!), height: CGFloat(truncating: self.height!))
//        frame = CGRect(x: 0, y: 0, width: CGFloat(truncating: self.width!), height: CGFloat(truncating: self.height!))
        addAdView()
        guard let onDidLoad = self.onDidLoad else { return }
        onDidLoad(["adUnitID": self.adUnitId!, "height": adView.frame.height, "width": adView.frame.width])
    }
    
    func configureView(for ad: YMANativeAd) {
        let assets = ad.adAssets()
        
        if let media = assets.media {
            //you can use the aspect ratio if you need it to determine the size of media view.
            print(String(format: "Media aspect ratio: %.2f", media.aspectRatio))
        }
    }
    
    func nativeAdLoader(_ loader: YMANativeAdLoader, didFailLoadingWithError error: Error) {
        
        guard let onDidFailLoading = self.onDidFailLoading else { return }
        
        onDidFailLoading(["adUnitID": self.adUnitId!, "error": error.localizedDescription])
    }
}

// MARK: - YMANativeAdDelegate

extension YaAdNativeView: YMANativeAdDelegate {
    
    func nativeAdDidClick(_ ad: YMANativeAd) {
        guard let onClick = self.onClick else { return }
        onClick(["adUnitID": self.adUnitId!])
    }
    
    func nativeAd(_ ad: YMANativeAd, didTrackImpressionWith impressionData: YMAImpressionData?) {
        guard let onDidTrackImpression = self.onDidTrackImpression else { return }
        onDidTrackImpression([
            "adUnitID": self.adUnitId!,
            "impressionData": impressionData?.description as Any
        ])
    }
    
    func nativeAdWillLeaveApplication(_ ad: YMANativeAd) {
        guard let onWillLeaveApp = self.onWillLeaveApp else { return }
        onWillLeaveApp(["adUnitID": self.adUnitId!])
    }
    
    func nativeAd(_ ad: YMANativeAd, willPresentScreen viewController: UIViewController?) {
        guard let onWillPresent = self.onWillPresent else { return }
        onWillPresent(["adUnitID": self.adUnitId!])
    }
    
    func nativeAd(_ ad: YMANativeAd, didDismissScreen viewController: UIViewController?) {
        guard let onDidDismiss = self.onDidDismiss else { return }
        onDidDismiss(["adUnitID": self.adUnitId!])
    }
    
    func close(_ ad: YMANativeAd) {
        adView?.isHidden = true
        guard let onClose = self.onClose else { return }
        onClose(["adUnitID": self.adUnitId!])
    }
    
}

