//
//  GeoStoreViewController.swift
//  NearbyStores
//
//  Created by DT Team on 6/30/18.
//  Copyright © 2018 Amine. All rights reserved.
//

import UIKit
import GoogleMaps
import Cosmos
import RealmSwift
import MapKit
import SwiftEventBus
import GooglePlaces
import Alamofire
import SwiftyJSON
import Firebase

struct LTDestination {
    
    var pickup_from: Int?
    var delivery_to: Int?
    var delivery_boy: Int?
    
    var cf_lat: Double?
    var cf_lng: Double?
    var cf_address: String?
    var cf_phone1: String?
    var cf_phone2: String?
    var cf_fullname: String?
    var order: Order?
    
}



class LocationTrackerController: MyUIViewController,GMSMapViewDelegate, CLLocationManagerDelegate, ContactPopupDelegate {
  
    var destination: LTDestination? = nil
    
    let locationManager = CLLocationManager()
    var currentLocation: CLLocationCoordinate2D? = nil


    static func newInstance() -> LocationTrackerController {
        let sb = UIStoryboard(name: "LocationTracker", bundle: nil)
        let ms: LocationTrackerController = sb.instantiateViewController(withIdentifier: "location_tracker_VC") as! LocationTrackerController
        return ms
    }

    
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        
        guard let locValue: CLLocationCoordinate2D = manager.location?.coordinate else { return }
        
        self.currentLocation = locValue
        
        Utils.printDebug("\(locations)")
        self.current_lat = locValue.latitude
        self.current_lng = locValue.longitude
        
       
        if let guest = Guest.getInstance(), let cl = self.currentLocation {
            
            
            let realm = try! Realm()
            try! realm.write {
                
                guest.lat = cl.latitude
                guest.lng = cl.longitude
                realm.add(guest,update: .all)
                
            }
            
            self.locationManager.stopUpdatingLocation()
            
        }
        
        DispatchQueue.main.asyncAfter(deadline: .now() + 15.0) {
            self.locationManager.startUpdatingLocation()
        }
        
    }
    
    
    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        
        
        if CLLocationManager.locationServicesEnabled() {
            switch CLLocationManager.authorizationStatus() {
            case .notDetermined, .restricted, .denied:
                self.requestLocation()
            case .authorizedAlways, .authorizedWhenInUse:
                self.requestLocation()
            }
        }
        
        
    }
    
    
    func requestLocation() {
        
        self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
        self.locationManager.requestWhenInUseAuthorization()
        self.locationManager.startUpdatingLocation()
        
    }
  
    var _req_limit = 30
    
    
    lazy var contactPopup: ContactPopupView = {
          let launcher = ContactPopupView()
         // launcher.mainController = self
          return launcher
      }()
    
    //store geo map header
    @IBOutlet weak var headerContainer: UIView!
    @IBOutlet weak var headerCloseBtn: UIButton!
    @IBOutlet weak var headerTitle: UILabel!
    @IBOutlet weak var headerAddress: UILabel!
    @IBOutlet weak var headerContactBtn: UIButton!

    @IBAction func header_contact_action(_ sender: Any) {
        
        contactPopup.show(id: 99999999)
        contactPopup.delegate = self
        
        contactPopup.mView?.left_contact_btn.setTitle("Call".localized, for: .normal)
        contactPopup.mView?.right_contact_btn.setTitle("Chat".localized, for: .normal)
        
    }
    
    @IBAction func header_close_action(_ sender: Any) {
        
        let animation = UIAnimation(view: self.headerContainer)
        animation.zoomOut()
        
    }
    
    
    func onLeftPressed(id: Int) { // call
        
        if is_owner_pressed{
            
            if let des = destination,let pickeup_from = des.pickup_from,
               let store = Store.findById(id: pickeup_from) {
                
                //call to store.tel
                 
                
                let phone = store.phone.replacingOccurrences(of: " ", with: "", options: .literal, range: nil)
                let result = phone.isValid(regex: .phone)
                
                if result{
                    
                    if let url = URL(string: "tel://\(phone)"), UIApplication.shared.canOpenURL(url) {
                        if #available(iOS 10, *) {
                            UIApplication.shared.open(url)
                        } else {
                            UIApplication.shared.openURL(url)
                        }
                    }else{
                        
                        let message: [String:String] = ["alert":"This app is not allowed to query for scheme tel".localized]
                        self.showAlertError(title: "Alert!".localized, content: message, msgBnt: "OK".localized)
                        
                    }
                    
                }else{
                    
                    let message: [String:String] = ["alert":"This app is not allowed to query for scheme tel or Phone number is not valid".localized]
                    self.showAlertError(title: "Alert!".localized, content: message, msgBnt: "OK".localized)
                    
                }
                
            }
            
        }else{
           
            
            if let des = destination, let delivery_to = des.delivery_to ,let client = User.findById(id: delivery_to) {
                
                //call to client.tel
                 
                var phone = ""
                
                if let p = des.cf_phone1{
                    phone = p.replacingOccurrences(of: " ", with: "", options: .literal, range: nil)
                }else if let p = des.cf_phone2{
                    phone = p.replacingOccurrences(of: " ", with: "", options: .literal, range: nil)
                }
          
                let result = phone.isValid(regex: .phone)
                
                if result{
                    if let url = URL(string: "tel://\(phone)"), UIApplication.shared.canOpenURL(url) {
                        if #available(iOS 10, *) {
                            UIApplication.shared.open(url)
                        } else {
                            UIApplication.shared.openURL(url)
                        }
                    }else{
                        
                        let message: [String:String] = ["alert":"This app is not allowed to query for scheme tel".localized]
                        self.showAlertError(title: "Alert!".localized, content: message, msgBnt: "OK".localized)
                        
                    }
                }else{
                    
                    let message: [String:String] = ["alert":"This app is not allowed to query for scheme tel or Phone number is not valid".localized]
                    self.showAlertError(title: "Alert!".localized, content: message, msgBnt: "OK".localized)
                    
                }
            }
            
        }
        
    }
    
    func onRightPressed(id: Int) { // chat
        
        if is_owner_pressed{
            
            if let des = destination,let pickup_from = des.pickup_from, let store = Store.findById(id: pickup_from) {
                
                //chat with store.id
                 
                let sb = UIStoryboard(name: "Messenger", bundle: nil)
                if sb.instantiateInitialViewController() != nil {
                    
                    let ms: MessengerViewController = sb.instantiateViewController(withIdentifier: "messengerVC") as! MessengerViewController
                    ms.client_id = store.user_id
                    self.present(ms, animated: true)
                }
            }
            
        }else{
           
            
            if let des = destination,let delivery_to = des.delivery_to, let client = User.findById(id: delivery_to) {
                
                //chat with client.id
                 
                let sb = UIStoryboard(name: "Messenger", bundle: nil)
                if sb.instantiateInitialViewController() != nil {
                    
                    let ms: MessengerViewController = sb.instantiateViewController(withIdentifier: "messengerVC") as! MessengerViewController
                    ms.client_id = client.id
                    self.present(ms, animated: true)
                }
            }
            
        }
    }
    
    
    @IBOutlet weak var navigationBar: UINavigationBar!
    @IBOutlet weak var navigationBarItem: UINavigationItem!
    @IBOutlet weak var viewContainer: UIView!
    
 
    
    //end
    @IBAction func zoomPlus(_ sender: Any) {
        
        if let mapView = self.mapView  {
            
            mapView.animate(toZoom: mapView.camera.zoom+1)
            
        }
        
    }
    
    @IBAction func zoomLess(_ sender: Any) {
        
        if let mapView = self.mapView  {
            mapView.animate(toZoom: mapView.camera.zoom-1)

        }
    }

    
    let topBarTitle: EdgeLabel = {
        
        let titleLabel = EdgeLabel()
        
        titleLabel.text = ""
        titleLabel.textColor = UIColor.white
        titleLabel.font = UIFont.systemFont(ofSize: 20)
        
        return titleLabel
        
    }()
    
    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 = "Map".localized
       
        navigationBarItem.titleView = topBarTitle
        
    }
   
    func setupNavBarButtons() {
        
        navigationBarItem.leftBarButtonItems = []
        navigationBarItem.rightBarButtonItems = []
        
        let color = AppDesignUtils.defaultModeColor(dark: .white, light: Colors.primaryColor)

        //arrow back icon
        var arrowImage: UIImage? = nil
        if Utils.isRTL(){
            arrowImage = UIImage.init(icon: .ionicons(.iosArrowForward), size: CGSize(width: 30, height: 30), textColor: color)
        }else{
            arrowImage = UIImage.init(icon: .ionicons(.iosArrowBack), size: CGSize(width: 30, height: 30), textColor: color)
        }
        
             
        let customBarButtonItem = UIBarButtonItem(image: arrowImage!, style: .plain, target: self, action: #selector(onBackHandler))
        

        customBarButtonItem.setIcon(icon: .ionicons(.iosArrowBack), iconSize: 25, color: color)
        navigationBarItem.leftBarButtonItems?.append(customBarButtonItem)
  
    }
    
  
    
    
    @objc func onBackHandler()  {
        self.dismiss(animated: true)
    }
    
    
    var mapView: GMSMapView? = nil
    
    var lastObject: Store? = nil
    @objc func onTapStoreHeader()  {
        if let object = lastObject{
           
            //show detail of store
            let sb = UIStoryboard(name: "StoreDetail", bundle: nil)
            if sb.instantiateInitialViewController() != nil {
                
                let ms: StoreDetailViewController = sb.instantiateViewController(withIdentifier: "storedetailVC") as! StoreDetailViewController
                ms.storeId = object.id
                
                self.present(ms, animated: true)
            }
        }
    }
    
    
    func setupBotton(){
    
        
        self.share_location_btn.setTitle("Open it outside".localized, for: .normal)
        self.share_location_btn.initBoldFont()
        self.share_location_btn.setTitleColor(.white, for: .normal)
        
        self.share_location_btn.backgroundColor = Colors.primaryColor
        self.share_btn_container.backgroundColor = Colors.primaryColor
        
    }
    
    
    @IBOutlet weak var share_btn_container: UIView!
    @IBOutlet weak var share_location_btn: UIButton!
    
    var selected_target_position: CLLocationCoordinate2D?
    var selected_target_name: String?
    
    @IBAction func share_location_Action(_ sender: Any) {
        
        if let position = selected_target_position, let name = selected_target_name{
            self.openMaps(latitude: position.latitude, longitude: position.longitude, title: name)
        }
    
    }
   
    func openMaps(latitude: Double, longitude: Double, title: String?) {
        
        let application = UIApplication.shared
        let coordinate = "\(latitude),\(longitude)"
        let encodedTitle = title?.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? ""
        let handlers = [
            ("Apple Maps", "http://maps.apple.com/?q=\(encodedTitle)&ll=\(coordinate)"),
            ("Google Maps", "comgooglemaps://?q=\(coordinate)"),
            ("Waze", "https://waze.com/ul?ll=\(coordinate)"),
            ("Citymapper", "citymapper://directions?endcoord=\(coordinate)&endname=\(encodedTitle)")
        ]
            .compactMap { (name, address) in URL(string: address).map { (name, $0) } }
            .filter { (_, url) in application.canOpenURL(url) }

        
        guard handlers.count > 1 else {
            if let (_, url) = handlers.first {
                if #available(iOS 10.0, *) {
                    application.open(url, options: [:])
                } else {
                    // Fallback on earlier versions
                }
            }
            return
        }
        
        let alert = UIAlertController(title: "Open it in".localized, message: nil, preferredStyle: .actionSheet)
        
        handlers.forEach { (name, url) in
            alert.addAction(UIAlertAction(title: name, style: .default) { _ in
                if #available(iOS 10.0, *) {
                    application.open(url, options: [:])
                } else {
                    // Fallback on earlier versions
                }
            })
        }
        
        alert.addAction(UIAlertAction(title: "Cancel".localized, style: .default) { _ in
            alert.dismiss(animated: true)

        })
        
        self.present(alert, animated: true, completion: nil)
        
    }
    var ref: DatabaseReference!
    
    func setup_firebase_database() {
    
        ref = Database.database().reference()
        
    }
    
    override func viewDidLoad() {
        
        super.viewDidLoad()
        setup_firebase_database()
        
        self.setupViewloader()
        self.setupBotton()
        self.setupHeader()
        
        //update location
        self.locationManager.delegate = self
        self.requestLocation()
        
        
        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)
        
        self.setupNavBarTitles()
        self.setupNavBarButtons()
        
        
        viewManager.showAsLoading(parent: self.view)

        if let guest = Guest.getInstance() {
            
            let camera = GMSCameraPosition.camera(withLatitude: guest.lat, longitude: guest.lng, zoom: 16)
            self.mapView = GMSMapView.map(withFrame: CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height), camera: camera)
            
            mapView?.delegate = self
            
            if let mapView = self.mapView  {
                mapView.animate(toZoom: 16)
                viewContainer.addSubview(mapView)

            }
           
        }
        
        //setup
        setupDelivery_BoyMarker()
        setupPickupFromMarker()
        setupDelivery_toMarker()
        locatAll()
        
    
    }
    
    func addPolyLine(from start: CLLocationCoordinate2D, to end: CLLocationCoordinate2D, waypoints: CLLocationCoordinate2D?)  {
        
        let sessionManager = NSGoogleMapsDirection()
        sessionManager.mode = NSGoogleMapsDirectionModeS.DRIVING
        
        sessionManager.requestDirections(from: start, to: end, waypoints: waypoints, completionHandler: { (path, error) in

               if let error = error {
                   print("Something went wrong, abort drawing!\nError: \(error)")
               } else {
                   // Create a GMSPolyline object from the GMSPath
                   let polyline = GMSPolyline(path: path!)
                
                  polyline.strokeColor = Colors.primaryColor
                  polyline.strokeWidth = 3

                   // Add the GMSPolyline object to the mapView
                   polyline.map = self.mapView

                   // Move the camera to the polyline
                   let bounds = GMSCoordinateBounds(path: path!)
                   let cameraUpdate = GMSCameraUpdate.fit(bounds, with: UIEdgeInsets(top: 40, left: 40, bottom: 40, right: 40))
                self.mapView!.animate(with: cameraUpdate)
               }

           })
    
        
    }

    var viewManager: LoaderViewManager =  LoaderViewManager()
    
    func setupViewloader()  {
        
        //setup view loader, Error, Empty layouts
        viewManager.setup(parent: viewContainer)
    }
    
    func setupPickupFromMarker()  {
        
        
        guard let guest = Guest.getInstance() else{
            return
        }
        
        if let mapView = self.mapView, let des = self.destination {
            
            
            guard let pickup_from = des.pickup_from, let store = Store.findById(id: pickup_from) else {
                return
            }
            
           
            // Creates a marker in the center of the map.
            let marker = GMSMarker()
            marker.position = CLLocationCoordinate2D(latitude:  store.latitude, longitude: store.longitude)
            marker.map = mapView
        
        
            let icon = CustomViewStoreMarker()
            icon.object = store
            icon.setup(marker: marker)
            
            marker.iconView = icon
         
        
           
            if des.delivery_to == nil{
                
                var from = CLLocationCoordinate2D()
                from.latitude = guest.lat
                from.longitude = guest.lng
                
                var to = CLLocationCoordinate2D()
                to.latitude = store.latitude
                to.longitude = store.longitude
                
                self.addPolyLine(from: from, to: to, waypoints: nil)
        
                let camera = GMSCameraPosition.camera(withLatitude: store.latitude, longitude: store.longitude, zoom: 16)
                
                
                
                DispatchQueue.main.asyncAfter(deadline: .now()+0.1) {
                    mapView.animate(to: camera)
                }
                
            
            }
          
            
            self.viewManager.showResult()
            
        }
    }
    
    
    func setupDelivery_toMarker()  {
        
        self.viewManager.showResult()
        
        
        guard let guest = Guest.getInstance() else{
            return
        }
           
        
        if let mapView = self.mapView, let des = self.destination {
            
            guard let cf_lat = des.cf_lat, let cf_lng = des.cf_lng else {
               return
            }

            
            guard let delivery_to = des.delivery_to,let client = User.findById(id: delivery_to) else {
                return
            }
            
            
            // Creates a marker in the center of the map.
            let marker = GMSMarker()
            marker.position = CLLocationCoordinate2D(latitude:  cf_lat, longitude: cf_lng)
            marker.map = mapView
        
            
            let icon = CustomViewStoreMarker()
            icon.object0 = client
            icon.setup(marker: marker)

            marker.iconView = icon
            
            
            if des.pickup_from == nil{
                
                let camera = GMSCameraPosition.camera(withLatitude: cf_lat, longitude: cf_lng, zoom: 16)
                mapView.camera = camera
                mapView.animate(toZoom: mapView.camera.zoom)
                
                var from = CLLocationCoordinate2D()
                from.latitude = guest.lat
                from.longitude = guest.lng
                
                var to = CLLocationCoordinate2D()
                to.latitude = cf_lat
                to.longitude = cf_lng
                
                self.addPolyLine(from: from, to: to, waypoints: nil)
          
                DispatchQueue.main.asyncAfter(deadline: .now()+0.1) {
                    mapView.animate(to: camera)
                }
            }
            
        }
    }
    
    func locatAll() {
        
        guard let mapView = self.mapView, let des = self.destination else{
            return
        }
        
        guard let cf_lat = des.cf_lat, let cf_lng = des.cf_lng else {
            return
        }
        
        guard let pickup_from = des.pickup_from, let store = Store.findById(id: pickup_from) else {
            return
        }
        
        //create polyline
        if let guest = Guest.getInstance() {
            
            var from = CLLocationCoordinate2D()
            from.latitude = guest.lat
            from.longitude = guest.lng
            
            var to = CLLocationCoordinate2D()
            to.latitude = cf_lat
            to.longitude = cf_lng
            
            var wp = CLLocationCoordinate2D()
            wp.latitude = store.latitude
            wp.longitude = store.longitude
            
            self.addPolyLine(from: from, to: to, waypoints: wp)
            
        }
        
    }
    
    
    
    func setupDelivery_BoyMarker()  {
        
        self.viewManager.showResult()
        
    
        if let guest = Guest.getInstance() {
           
            // Creates a marker in the center of the map.
            let marker = GMSMarker()
            marker.position = CLLocationCoordinate2D(latitude:  guest.lat, longitude: guest.lng)
            marker.map = mapView
        
            
        }
    }
   
    
    func setupHeader()  {
        
        
        self.headerContainer.isHidden = true
        self.headerCloseBtn.setIcon(icon: .ionicons(.androidClose), iconSize: 24, color: Colors.gray, forState: .normal)
        self.headerTitle.initBolodFont()
        self.headerAddress.initDefaultFont()
        self.headerAddress.textColor = .darkGray
        self.headerContactBtn.setTitle("Contact".localized, for: .normal)
        self.headerContactBtn.setCustomButtonControlStyle(active: true)
        self.headerContactBtn.initBoldFont()
        
        
    }
    

    var current_lat = 0.0
    var current_lng = 0.0
    
    func mapView(_ mapView: GMSMapView, didChange position: GMSCameraPosition) {
       
        current_lat = position.target.latitude
        current_lng = position.target.longitude

    }
    

    var is_owner_pressed = false
    
    func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
        
        
        if(marker.iconView != nil ){
            
            let view: CustomViewStoreMarker = marker.iconView as! CustomViewStoreMarker
            if let object = view.object { //owner tap
                
                object.save()
              
                
                headerTitle.text = object.name
                headerAddress.text = object.address
                
                headerAddress.isHidden = false
                //headerContainer.isHidden = false
                
              
                let animation = UIAnimation(view: self.headerContainer)
                animation.zoomIn()
                
                
                is_owner_pressed = true
                
                
            }else  if let object = view.object0 { //client tap
                
                object.save()
                
                if let cf_fullname = self.destination?.cf_fullname{
                    headerTitle.text = cf_fullname
                }else{
                    headerTitle.text = object.name
                }
                
              
                if let cf_address = self.destination?.cf_address{
                    headerAddress.text = cf_address
                }
               
                headerAddress.isHidden = false
              
                let animation = UIAnimation(view: self.headerContainer)
                animation.zoomIn()
                
                is_owner_pressed = false
                
                
            }
        }
        
       
        return true
    }
  
 
}

struct NSGoogleMapsDirectionModeS {
    static let DRIVING = "driving"
    static let WALKING = "walking"
    static let BICYCLING = "bicycling"
    static let TRANSIT = "transit"
}


class NSGoogleMapsDirection {
    
    var mode = NSGoogleMapsDirectionModeS.DRIVING
    
    let GOOGLE_DIRECTIONS_API_KEY = AppConfig.GOOGLE_DIRECTIONS_KEY

    func requestDirections(from start: CLLocationCoordinate2D, to end: CLLocationCoordinate2D, waypoints: CLLocationCoordinate2D?,  completionHandler: @escaping ((_ response: GMSPath?, _ error: Error?) -> Void)) {
        
        var waypoints_s = ""
        if let wp = waypoints{
            waypoints_s = "&waypoints=\(wp.latitude),\(wp.longitude)"
        }
        
        guard let url = URL(string: "https://maps.googleapis.com/maps/api/directions/json?origin=\(start.latitude),\(start.longitude)&destination=\(end.latitude),\(end.longitude)\(waypoints_s)&mode=\(mode)&key=\(GOOGLE_DIRECTIONS_API_KEY)") else {
            let error = NSError(domain: "LocalDomain", code: 0, userInfo: [NSLocalizedDescriptionKey: "Failed to create object URL"])
            print("Error: \(error)")
            completionHandler(nil, error)
            return
        }

        // Set up the session
        let config = URLSessionConfiguration.default
        let session = URLSession(configuration: config)

        let task = session.dataTask(with: url) { (data, response, error) in
            // Check if there is an error.
            guard error == nil else {
                DispatchQueue.main.async {
                    print("Google Directions Request Error: \((error!)).")
                    completionHandler(nil, error)
                }
                return
            }

            // Make sure data was received.
            guard let data = data else {
                DispatchQueue.main.async {
                    let error = NSError(domain: "GoogleDirectionsRequest", code: 0, userInfo: [NSLocalizedDescriptionKey: "Failed to receive data"])
                    print("Error: \(error).")
                    completionHandler(nil, error)
                }
                return
            }

            do {
                // Convert data to dictionary.
                guard let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] else {
                    DispatchQueue.main.async {
                        let error = NSError(domain: "GoogleDirectionsRequest", code: 2, userInfo: [NSLocalizedDescriptionKey: "Failed to convert JSON to Dictionary"])
                        print("Error: \(error).")
                        completionHandler(nil, error)
                    }
                    return
                }

                // Check if the the Google Direction API returned a status OK response.
                guard let status: String = json["status"] as? String, status == "OK" else {
                    DispatchQueue.main.async {
                        let error = NSError(domain: "GoogleDirectionsRequest", code: 3, userInfo: [NSLocalizedDescriptionKey: "Google Direction API did not return status OK"])
                        print("Error: \(error).")
                        completionHandler(nil, error)
                    }
                    return
                }

                print("Google Direction API response:\n\(json)")

                // We only need the 'points' key of the json dictionary that resides within.
                if let routes: [Any] = json["routes"] as? [Any], routes.count > 0, let routes0: [String: Any] = routes[0] as? [String: Any], let overviewPolyline: [String: Any] = routes0["overview_polyline"] as? [String: Any], let points: String = overviewPolyline["points"] as? String {
                    // We need the get the first object of the routes array (route0), then route0's overview_polyline and finally overview_polyline's points object.

                    if let path: GMSPath = GMSPath(fromEncodedPath: points) {
                        DispatchQueue.main.async { [self] in
                            
                            self.getRoadData(routes: routes as NSArray)
                            completionHandler(path, nil)
                        }
                        return
                    } else {
                        DispatchQueue.main.async {
                            let error = NSError(domain: "GoogleDirections", code: 5, userInfo: [NSLocalizedDescriptionKey: "Failed to create GMSPath from encoded points string."])
                            completionHandler(nil, error)
                        }
                        return
                    }

                } else {
                    DispatchQueue.main.async {
                        let error = NSError(domain: "GoogleDirections", code: 4, userInfo: [NSLocalizedDescriptionKey: "Failed to parse overview polyline's points"])
                        completionHandler(nil, error)
                    }
                    return
                }


            } catch let error as NSError  {
                DispatchQueue.main.async {
                    completionHandler(nil, error)
                }
                return
            }

        }

        task.resume()
    }
    
    func getRoadData(routes: NSArray)  {
    
    
        if (routes.count > 0) {
            let overview_polyline = routes[0] as? NSDictionary
            let dictPolyline = overview_polyline?["overview_polyline"] as? NSDictionary
            let points = dictPolyline?.object(forKey: "points") as? String

            DispatchQueue.main.async {
                //
                let legs = overview_polyline?["legs"] as! Array<Dictionary<String, AnyObject>>

                
                var total_duration = 0.0
                var total_distance = 0.0
                
                for leg in legs{
                    
                    let distance = leg["distance"] as? NSDictionary
                    let distanceValue = distance?["value"] as? Double ?? 0.0
                    total_distance = total_distance + distanceValue
                    
                    
                    let duration = legs[0]["duration"] as? NSDictionary
                    let totalDurationInSeconds = duration?["value"] as? Int ?? 0
                    total_duration = Double(totalDurationInSeconds) +  total_duration
                }
               

                let miles = Double(total_distance) / 1609.344
                let km = Double(total_distance) / 1000.0
                
                let  duraction_in_min = total_duration / 60

                Utils.printDebug("\(duraction_in_min) mins - \(miles) miles -  \(km) km")
                
                 

            }
        }
        else {
           
        }
        
    }
}

