//
//  BusinessManagerViewcController.swift
//  NearbyStoresPro
//
//  Created by Amine  on 3/22/20.
//  Copyright © 2020 Amine. All rights reserved.
//

import UIKit
import WebKit
import PassKit

protocol MakePaymentControllerDelegate {
    func done(controller: MakePaymentController)
    func failed(errors: [String: String], controller: MakePaymentController)
}

class MakePaymentController: MyUIViewController, ErrorLayoutDelegate, EmptyLayoutDelegate, WKNavigationDelegate{
   
    
    var delegate: MakePaymentControllerDelegate?
    
    func onReloadAction(action: ErrorLayout) {
        
    }
    
    func onReloadAction(action: EmptyLayout) {
        
    }
    
    @IBOutlet weak var navigationBar: UINavigationBar!
    @IBOutlet weak var navigationBarItem: UINavigationItem!
    @IBOutlet weak var view_container: UIView!
    @IBOutlet weak var activity_indicator: UIActivityIndicatorView!
    
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        activity_indicator.color = AppDesignUtils.defaultModeColor(dark: .white, light: Colors.primaryColor)
        
        setupNavigationBar()
        setupNavBarButtons()
        setupNavBarTitles()
       
        topBarTitle.text = "Checkout".localized
        
        
        
        if let sess = Session.getInstance(), let user = sess.user{
            
            
            if(self.payment_link == ""){
                
            }
            
            
            setupWebView()
        }

        
    }
    
    
    func setupNavigationBar() {
        self.navigationBar.isTranslucent = false
        self.navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
        self.navigationBar.shadowImage = UIImage()
        self.navigationBar.tintColor = AppDesignUtils.defaultModeColor(dark: .white, light: Colors.primaryColor)
        
    }
    
    func setupNavBarTitles() {
           
           let rect = CGRect(x: 0, y: 0, width: view.frame.width - 32, height: view.frame.height)
           topBarTitle.frame = rect
           topBarTitle.textColor = AppDesignUtils.defaultModeColor(dark: .white, light: Colors.primaryColor)
           topBarTitle.font = UIFont(name: AppConfig.Design.Fonts.regular, size: 17)
           topBarTitle.leftTextInset = 5
           
           topBarTitle.text = Bundle.main.object(forInfoDictionaryKey: "CFBundleDisplayName") as? String
           
           navigationBarItem.titleView = topBarTitle

       }
    
    let topBarTitle: EdgeLabel = {

         let titleLabel = EdgeLabel()

         let appname = Bundle.main.object(forInfoDictionaryKey: "CFBundleName") as? String ?? "Home".localized

         titleLabel.text = appname
         titleLabel.textColor = AppDesignUtils.defaultModeColor(dark: .white, light: Colors.primaryColor)
         titleLabel.font = UIFont.systemFont(ofSize: 20)

         return titleLabel

     }()
    
    
    func setupNavBarButtons() {
           
           //arrow back icon
           var icon: UIImage? = nil
            icon = UIImage.init(icon: .googleMaterialDesign(.close), size: CGSize(width: 30, height: 30), textColor: Colors.primaryColor)
           

           let _color = AppDesignUtils.defaultModeColor(dark: .white, light: Colors.primaryColor)
           let customBackButtonItem = UIBarButtonItem(image: icon!, style: .plain, target: self, action: #selector(onBackHandler))
           customBackButtonItem.setIcon(icon: .ionicons(.iosArrowBack), iconSize: 25, color: _color)
           
           
           navigationBarItem.leftBarButtonItems = []
           navigationBarItem.rightBarButtonItems = []
           
        navigationBarItem.leftBarButtonItems?.append(customBackButtonItem)
           
           
       }
    
    
    var customOptionsButtonItem:UIBarButtonItem?
    func addCraeteNavigationBarButton() {
        
        let icon = UIImage.init(icon: .ionicons(.androidMoreVertical), size: CGSize(width: 30, height: 30), textColor: Colors.primaryColor)
        
        let _color = AppDesignUtils.defaultModeColor(dark: .white, light: Colors.primaryColor)
        customOptionsButtonItem = UIBarButtonItem(image: icon, style: .plain, target: self, action: #selector(onCreateHandler))
        customOptionsButtonItem!.setIcon(icon: .ionicons(.iosArrowBack), iconSize: 25, color: _color)
        
        navigationBarItem.rightBarButtonItems = []
        navigationBarItem.rightBarButtonItems?.append(customOptionsButtonItem!)
        
    }
    
    @objc func onCreateHandler()  {
        
        let dict = [
                   "device": "ios",
                   "action": "manage_business_options"
               ]
        let jsonData = try! JSONSerialization.data(withJSONObject: dict, options: [])
        let jsonString = String(data: jsonData, encoding: String.Encoding.utf8)!

       
        if let _webview = self.webView{
            _webview.evaluateJavaScript("handle_device_events(\(jsonString))") { result, error in
                guard error == nil else {
                    //print(error)
                    return
                }
            }
        }
        
    }

    
    @objc func onBackHandler()  {
    
        if let controller = self.navigationController{
            //controller.navigationBar.isHidden = true
            controller.popViewController(animated: true)
            ////controller.navigationBar.isHidden = false
        }else{
            self.dismiss(animated: true)
        }
        
    }
    
    
    var payment_link:String? = ""
    var webView: WKWebView?

    
    private func setupWebView(){
        
        
        //init webview
        self.webView = WKWebView()
        self.webView?.frame = self.view_container.frame
        if let _webView  = self.webView {
            
            self.view_container.addSubview(_webView)
            
            self.view_container.addConstraintsWithFormat(format: "H:|[v0]|", views: _webView)
            self.view_container.addConstraintsWithFormat(format: "V:|[v0]|", views: _webView)
            
            _webView.navigationDelegate = self
            _webView.translatesAutoresizingMaskIntoConstraints = false
            
            _webView.isHidden = true
            
        }
        
        //start loding
        
        if let _webView = self.webView{
                   
            self.activity_indicator.isHidden = false
            self.activity_indicator.startAnimating()
            
            

            guard let sess = Session.getInstance(), let user = sess.user else {
                return
            }
            
            var urlString = payment_link!.toBase64().addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
    
           
            
            let call_link = String(format: "%@?redirect=%@&token=%@", arguments: [
                AppConfig.Api.base_url+"/order_payment/link_call",
                urlString!,
                user.token,
                ]
            )
            
            // Getting a URL from our components is as simple as
            // accessing the 'url' property.
      
            Utils.printDebug("urlString = \(urlString)")
            Utils.printDebug("call_link = \(call_link)")
            
            let url = URL(string: call_link)!
            _webView.load(URLRequest(url: url))
                            
            _webView.isHidden = false
            _webView.allowsBackForwardNavigationGestures = true
                              
            self.view.layoutIfNeeded()
                   
        }
    }
    
  
    
    func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
        
        self.activity_indicator.isHidden = false
        navigationBarItem.rightBarButtonItems = []
        
    }
    
    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: (WKNavigationActionPolicy) -> Void) {
          if let url = navigationAction.request.url?.absoluteString {
            Utils.printDebug("BusinessManager: \(url)")
            checkCallbackURL(url: url)
          }
          
          decisionHandler(.allow)
      }
    
    
    func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
                                 
           
           if let response = navigationResponse.response as? HTTPURLResponse {
               if response.statusCode != 200 {
                   self.webView?.isHidden = false
                   let message = "Error \(response.statusCode)"
                   self.showAlertError(title: "Error",content: ["":message] ,msgBnt: "OK")
                   decisionHandler(.allow)
                   return
               }else{
                
            }
           }
           
           decisionHandler(.allow)
       }
    

    
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        
        self.activity_indicator.isHidden = true
        self.addCraeteNavigationBarButton();
        
        let javascript = "document.title\n"
        
        if let title = webView.title{
            self.topBarTitle.text = title
        }

    }
    
    var links:[String] = []
    
    func checkCallbackURL(url: String) -> Bool {
       
        
        Utils.printDebug("\(url)")
        
        let requestURLString = url
        
       if  requestURLString.contains("payment/process_payment") && requestURLString.regMatchGroup(regex: "mp=10012").count > 0{
        
        
        guard let invoiceid = requestURLString.getIdFromUrl(pattern: "invoiceid") else {
            self.onBackHandler()
            return false
        }
        
       
       
        let params = [
            "invoiceId": invoiceid
        ]
        
        MyProgress.show(parent: self.view)
        
        let api = SimpleRequestApi()
        
        
        Utils.printDebug("\(AppConfig.Api.base_url_api+"/"+Constances.Api.API_VERSION+"/payment/getInvoice")")
        
        api.run(url: AppConfig.Api.base_url_api+"/"+Constances.Api.API_VERSION+"/payment/getInvoiceForApplePay", parameters: params) { parser in
            
            MyProgress.dismiss()
            
            if parser?.success == 1, let result = parser?.result{
               
                self.invoiceId = invoiceid
               
                
              /*  guard let roundedF =  else{
                    if let del = self.delegate{
                        del.failed(errors: ["err":"Amount is invalid"], controller: self)
                    }
                    return
                }*/
                Utils.printDebug("\(String(format: "%.2f", result["details_subtotal"].floatValue))")
               
                let amount_to_pay = result["details_subtotal"].doubleValue.round(to: 2)
                let currency = result["currency"].stringValue
            
                Utils.printDebug("\(amount_to_pay)")
              
                //proccess the payment using apple pay
                var paymentRequest: PKPaymentRequest = {
                        let request = PKPaymentRequest()
                    request.merchantIdentifier = AppConfig.ApplePayConfig.merchantIdentifier
                    request.supportedNetworks = AppConfig.ApplePayConfig.supportedNetworks
                        if #available(iOS 11.0, *) {
                           // request.supportedCountries = AppConfig.ApplePayConfig.supportedCountries
                        } else {
                            // Fallback on earlier versions
                            self.onBackHandler()
                        }
                        request.merchantCapabilities = .capability3DS
                        request.countryCode = AppConfig.ApplePayConfig.codeCountry
                        request.currencyCode = currency
                    request.paymentSummaryItems = [PKPaymentSummaryItem(label: AppConfig.APP_NAME, amount: NSDecimalNumber(value: amount_to_pay))]
                        return request
                    }()
                
                
                if let controller = PKPaymentAuthorizationViewController(paymentRequest: paymentRequest) {
                    controller.delegate = self
                    self.present(controller, animated: true, completion: nil)
                }
                
        
                
            }else{
                self.onBackHandler()
            }
            
        }
        
        
            return false;
        }
        
        
        if requestURLString.hasPrefix(AppConfig.Api.base_url) && requestURLString != payment_link {
            
            if !requestURLString.contains("order_payment") || !requestURLString.contains("payment"){
               if let del = delegate{
                  //  del.failed(errors: ["err":"Payment error"], controller: self)
                }
            }
           // links.append(requestURLString)
            if requestURLString.contains("order_payment/payment_done"){
                
                if let del = delegate{
                    del.done(controller: self)
                }
                
                
            }else if  requestURLString.contains("order_payment/payment_error"){
                
                if let del = delegate{
                    
                    let id = Int(requestURLString.getIdFromUrl(pattern: "error")!)
                    if(id == 29782){
                        del.failed(errors: ["err":"You don't have enough balance in your wallet. Use top-up feature to add balance.".localized], controller: self)
                    }else{
                        del.failed(errors: ["err":"Payment error"], controller: self)
                    }
                    
               
                }
                
            }
            
            return false;
        }
        return true
    }
   
    
    var invoiceId: String? = nil
    var isApplePaySucceesed = false
 
   
   
}

extension MakePaymentController: PKPaymentAuthorizationViewControllerDelegate {
 
    @available(iOS 11.0, *)
    func paymentAuthorizationViewController(_ controller: PKPaymentAuthorizationViewController, didAuthorizePayment payment: PKPayment, handler completion: @escaping (PKPaymentAuthorizationResult) -> Void) {
        
        let token = payment.token
        let transactionIdentifier = token.transactionIdentifier
        let paymentMethod = token.paymentMethod.displayName
        
        MyProgress.show(parent: self.view)
        
        guard let ivid = self.invoiceId else {
            self.showAlertError(title: "Payment error".localized, content: ["" : "Invoice ID is missed!".localized], msgBnt: "OK".localized)
            return
        }
        
        let api = SimpleRequestApi()
        
        var parameters = [
            "invoiceId": ivid,
            "transactionId": transactionIdentifier,
            "paymentMethod": "ApplePay:\(paymentMethod!)"
        ]
        
        if let sess = Session.getInstance(), let user = sess.user{
            parameters["user_id"] = String(user.id)
        }
        
        api.run(url: AppConfig.Api.base_url_api+"/"+Constances.Api.API_VERSION+"/payment/updateInvoiceApplePay", parameters: parameters) { parser in
            
            MyProgress.dismiss()
            
            if parser?.success == 1{
                self.isApplePaySucceesed = true
                completion(PKPaymentAuthorizationResult(status: .success, errors: nil))
            }else{
                self.showAlertError(title: "Payment error".localized, content: ["" : "occurred error during making the payment".localized], msgBnt: "OK".localized)
                completion(PKPaymentAuthorizationResult(status: .failure, errors: nil))
            }
            
        }
        
    }
    
  
    func paymentAuthorizationViewControllerDidFinish(_ controller: PKPaymentAuthorizationViewController) {
        
        MyProgress.dismiss()
        
        
        controller.dismiss(animated: true, completion: nil)
        
        if let del = self.delegate{
            if  self.isApplePaySucceesed {
                del.done(controller: self)
            }else{
                del.failed(errors: ["err":"Apple pay failed"], controller: self)
            }
        }
    }
    
    func updateInvoice(invoiceid: String,transactionId: String) {
        
     
    }

}

extension String {

    func fromBase64() -> String? {
        guard let data = Data(base64Encoded: self) else {
            return nil
        }

        return String(data: data, encoding: .utf8)
    }

    func toBase64() -> String {
        return Data(self.utf8).base64EncodedString()
    }

}


extension String {
    func getIdFromUrl(pattern: String) -> String? {
        return URLComponents(string: self)?.queryItems?.first(where: { $0.name == pattern })?.value
    }
}


extension String {
    func regMatchGroup(regex: String) -> [[String]] {
    do {
        var resultsFinal = [[String]]()
        let regex = try NSRegularExpression(pattern: regex, options: [])
        let nsString = self as NSString
        let results = regex.matches(in: self,
            options: [], range: NSMakeRange(0, nsString.length))
        for result in results {
            var internalString = [String]()
            
            for i in 0..<result.numberOfRanges {
                internalString.append(nsString.substring(with: result.range(at: i)))
            }
            resultsFinal.append(internalString)
        }
        return resultsFinal
       } catch let error as NSError {
           print("invalid regex: \(error.localizedDescription)")
           return [[]]
       }
    }
   
}


extension Double {
    func round(to places: Int) -> Double {
        let divisor = pow(10.0, Double(places))
        return (self * divisor).rounded() / divisor
    }
}
