//
//  NativeViewController.swift
//  sdk-demo-ios
//
//  Created by Smaato Inc on 15.04.20.
//  Copyright © 2020 Smaato Inc. All rights reserved.
//

import UIKit
import SmaatoSDKNative

enum NativeAdsTip: String {
    case TryLoadTip = "Tap ‘Load’ to load Native"
    case LoadingTip = "Native loading…"
    case LoadedTip = "Native was loaded successfully"
    case ClickedTip = "Native has been clicked"
    case ErrorTip = "Something failed. See console logs."
    case NoTip = ""
}

class NativeViewController: UIViewController {
    
    enum NativeViewRenderingMode {
        case manualByPublisher
        case autoBySDK
    }
    
    // Use own publisherId and adSpaceId from Dashboard settings to verify your ads
    // publisherId = "1100042525" and adSpaceId = "130783664" are default values for test ads presentation
    public var adSpaceId: String!
    
    // Feel free to change renderingMode mode and know more about possible ways of Native ads displaying on the screen
    public var renderingMode: NativeViewRenderingMode?
    
    // Native view container ad object
    private var nativeView: UIView?
    // Native ad object. You should retain this object to receive callback notifications
    private var nativeAd: SMANativeAd?

    // Helper UI controls
    @IBOutlet private weak var scrollView: UIScrollView!
    @IBOutlet private weak var buttonShow: UIButton!
    @IBOutlet private weak var switchShowImmediately: UISwitch!
    @IBOutlet private weak var publisherIdLabel: UILabel!
    @IBOutlet private weak var adspaceIdLabel: UILabel!
    @IBOutlet private weak var adBlock: AdBlockView!

    @IBOutlet private weak var nativeDidLoadLabel: UILabel!
    @IBOutlet private weak var nativeDidFailLabel: UILabel!
    @IBOutlet private weak var nativeWillPresentModalContentLabel: UILabel!
    @IBOutlet private weak var nativeDidPresentModalContentLabel: UILabel!
    @IBOutlet private weak var nativeDidDismissModalContentLabel: UILabel!
    @IBOutlet private weak var nativeDidClickLabel: UILabel!
    @IBOutlet private weak var nativeDidTTLExpireLabel: UILabel!
    @IBOutlet private weak var nativeWillLeaveAppLabel: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
        setupUI()
    }

    //MARK: Actions

    @IBAction private func btnLoadTapped(_ sender: Any) {
        resetLabels()

        // Remove old native from the screen if it exists
        nativeView?.removeFromSuperview()
        nativeAd = nil
        
        buttonShow.isEnabled = false
        adBlock.tip = NativeAdsTip.LoadingTip.rawValue

        // Load new Native ads
        nativeAd = loadNativeAd(with: adSpaceId)
    }

    @IBAction private func btnShowTapped(_ sender: Any) {
        buttonShow.isEnabled = false
        addNativeViewOnScreen(nativeView)
    }

    //MARK: Private

    private func setupUI() {
        adBlock.tip = NativeAdsTip.TryLoadTip.rawValue
        publisherIdLabel.text = SmaatoSDK.publisherId
        adspaceIdLabel.text = adSpaceId
        
        let mode = renderingMode ?? .manualByPublisher
        switch mode {
        case .manualByPublisher:
            switchShowImmediately.isEnabled = true
        case .autoBySDK:
            switchShowImmediately.isEnabled = false
        }

        if #available(iOS 11.0, *) {
            scrollView.contentInsetAdjustmentBehavior = .never
        } else {
            // Fallback on earlier versions
            automaticallyAdjustsScrollViewInsets = false
        }
    }

    func resetLabels() {
        nativeDidLoadLabel.alpha = 0.2
        nativeDidFailLabel.alpha = 0.2
        nativeWillPresentModalContentLabel.alpha = 0.2
        nativeDidPresentModalContentLabel.alpha = 0.2
        nativeDidDismissModalContentLabel.alpha = 0.2
        nativeDidClickLabel.alpha = 0.2
        nativeDidTTLExpireLabel.alpha = 0.2
        nativeWillLeaveAppLabel.alpha = 0.2
    }
}

extension NativeViewController: SMANativeAdDelegate {
   
    //MARK: Native ads helper methods
    
    private func loadNativeAd(with adspaceId: String?) -> SMANativeAd? {
        guard let smaatoId = adspaceId,
              let adRequest = SMANativeAdRequest(adSpaceId: smaatoId) else {
           print("Expect for valid adspaceId")
           return nil
        }

        let nativeAd = SMANativeAd()
        adRequest.allowMultipleImages = false
        adRequest.returnUrlsForImageAssets = false
        nativeAd.delegate = self
        nativeAd.load(with: adRequest)
        
        return nativeAd
    }
    
    private func addNativeViewOnScreen(_ adView: UIView?) {
        adBlock.tip = NativeAdsTip.NoTip.rawValue
        guard let _ = nativeAd,
              let adContainer = adView else {
            print("Native ads has not been loaded yet")
            return
        }
        
        adContainer.frame = adBlock.bounds
        adContainer.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        adBlock.addSubview(adContainer)
    }
    
    private func doManualRendering(renderer: SMANativeAdRenderer) -> UIView? {
        guard let adView = NativeAdCustomView.instantiateFromNib() else {
            return nil
        }

        renderer.registerView(forImpression: adView)
        renderer.registerViews(forClickAction: [adView.titleTextLabel,  adView.mainTextLabel, adView.mainImageView, adView.iconImageView, adView.ctaLabel])

        let assets = renderer.nativeAssets
        adView.titleTextLabel.text = assets.title
        adView.mainTextLabel.text = assets.mainText
        adView.sponsoredLabel.text = assets.sponsored
        
        if let image = assets.icon?.image {
            adView.iconImageView.image = image
        } else {
            print("Icon image has not been downloaded. Probably you have set `returnUrlsForImageAssets` property of `SMANativeAdRequest` object to `true` or URL link was broken")
        }
        
        if let image = assets.images?.first?.image {
            adView.mainImageView.image = image
        } else {
            print("Main image has not been downloaded. Probably you have set `returnUrlsForImageAssets` property of `SMANativeAdRequest` object to `true` or URL link was broken")
        }

        buttonShow.isEnabled = true
        return adView
    }
      
    private func doAutoRendering(renderer: SMANativeAdRenderer) -> UIView? {
        guard let adView = NativeAdSmaatoView.instantiateFromNib() else {
            return nil
        }

        renderer.renderAd(in: adView) {[weak self, weak adRenderer = renderer] (success, error) in
            guard let this = self,
                let renderer = adRenderer else {
              print("No destination for ad")
              return
            }
          
            if (success) {
              print("Native ad has been rendered")
              renderer.registerView(forImpression: adView)
              renderer.registerViews(forClickAction: [adView.smaTitleLabel!, adView.smaMainTextLabel!, adView.smaIconView!, adView.smaMediaView!, adView.smaCTALabel!])
              this.buttonShow.isEnabled = true
            } else {
              print("Native ad rendering error \(error?.localizedDescription ?? "")")
            }
        }
        
        return adView
    }
 
    //MARK: <SMANativeAdDelegate> Required methods
    
    func nativeAd(_ nativeAd: SMANativeAd, didLoadWith renderer: SMANativeAdRenderer) {
        NSLog("\(nativeAd) loaded successfully")
        adBlock.tip = NativeAdsTip.LoadedTip.rawValue
        nativeDidLoadLabel.alpha = 1
    
        let mode = renderingMode ?? .manualByPublisher
        switch mode {
        case .manualByPublisher:
            nativeView = doManualRendering(renderer: renderer)
            if (switchShowImmediately.isOn) {
                addNativeViewOnScreen(nativeView)
            }
        case .autoBySDK:
            nativeView = doAutoRendering(renderer: renderer)
        }
    }
    
    func nativeAd(_ nativeAd: SMANativeAd, didFailWithError error: Error) {
        NSLog("\(nativeAd) failed with error: \(error)")
        adBlock.tip = NativeAdsTip.ErrorTip.rawValue
        nativeDidFailLabel.alpha = 1
    }
    
    func presentingViewController(for nativeAd: SMANativeAd) -> UIViewController {
        return self
    }
    
    func nativeAdDidTTLExpire(_ nativeAd: SMANativeAd) {
        NSLog("\(nativeAd) TTL has expired and you can not use this Native from now. Please load new one. Tip: show Native before expiration for the best fill rate (you have about 5 minutes after loading completion).")
        nativeDidTTLExpireLabel.alpha = 1
    }
    
    //MARK: <SMANativeAdDelegate> Optional methods
    
    func nativeAdDidClick(_ nativeAd: SMANativeAd) {
        NSLog("\(nativeAd) has been clicked")
        adBlock.tip = NativeAdsTip.ClickedTip.rawValue
        nativeDidClickLabel.alpha = 1
    }
    
    func nativeAdWillPresentModalContent(_ nativeAd: SMANativeAd) {
        NSLog("\(nativeAd) will present a modal content")
        nativeWillPresentModalContentLabel.alpha = 1
    }
    
    func nativeAdDidPresentModalContent(_ nativeAd: SMANativeAd) {
        NSLog("\(nativeAd) did present a modal content")
        nativeDidPresentModalContentLabel.alpha = 1
    }

    func nativeAdDidDismissModalContent(_ nativeAd: SMANativeAd) {
        NSLog("\(nativeAd) did dissmiss a modal content")
        nativeDidDismissModalContentLabel.alpha = 1
    }
    
    func nativeAdWillLeaveApplication(from nativeAd: SMANativeAd) {
        NSLog("\(nativeAd) will leave application")
        nativeWillLeaveAppLabel.alpha = 1
    }

}
