//
//  OrderMapDistanceVc.swift
//  VattiCSS
//
//  Created by WZR on 2023/9/6.
//

import UIKit
import AMapSearchKit
public struct R_OrderMapDistance {
    ///showType：1、出发；2、到达签到
    static func router(_ orderId: String, data:M_OrderDetailInfo, showType:Int = 1, callback: ((Bool)->Void)?) {
        let vc = OrderMapDistanceVc.cd_storyboard("Order", from: "OrderMapDistanceVc") as! OrderMapDistanceVc
        vc.orderId = orderId
        vc.data = data
        vc.showType = showType
        vc.callback = callback
        CD.push(vc)
    }
}

class OrderMapDistanceVc: UIViewController {
    @IBOutlet weak var mapBgView: UIView!
    @IBOutlet weak var lab_txt: UILabel!
    @IBOutlet weak var lab_distance: UILabel!
    @IBOutlet weak var lab_tips: UILabel!
    @IBOutlet weak var lab_goOff: UILabel!
    @IBOutlet weak var lab_departurePoint: UILabel!
    @IBOutlet weak var lab_arrivalPoint: UILabel!
    @IBOutlet weak var btn_sign: UIButton!
    @IBOutlet weak var infoView: UIView!
    @IBOutlet weak var lab_unit: UILabel!
    
    var showType:Int = 1
    var orderId = ""
    var data = M_OrderDetailInfo()
    
    var completionBlock: AMapLocatingCompletionBlock!
    lazy var locationManager = AMapLocationManager()
    
    let search = AMapSearchAPI()
    let mapView = MAMapView()
    var polyLine = MAPolyline()
    
    var curLocation = CLLocation()
    
    var destination = AMapGeoPoint()
    var onDoorLocation = ""
    
    var curAddress = ""
    
    var callback: ((Bool)->Void)?
    
    var isOpenLocation = false
    override func viewDidLoad() {
        super.viewDidLoad()
        if !data.lat.isEmpty && !data.lnt.isEmpty && data.notMaintainedAK != 1 {
            NotificationCenter.default.addObserver(forName: Notification.Name(UIApplication.didBecomeActiveNotification.rawValue), object: UIApplication.shared, queue: OperationQueue.main) {[weak self] _ in
                guard let weakSelf = self else {return}
                weakSelf.geocodeSearch()
            }
        }
        setNavigationBackButton()
        
        switch showType {
        case 1:
            self.title = "确认出发".languageString()
            self.lab_txt.cd.text("\("全程".languageString())  ")
            lab_tips.cd.isHidden(true)
            btn_sign.cd.text("确认出发".languageString())
            lab_goOff.cd.text("\("出发时间".languageString())：\(Date().getDateStr(isEnglish() ? "MMM d HH:mm:ss" : "MM月dd日 HH:mm:ss"))")
        case 2:
            self.title = "到达签到".languageString()
            lab_txt.cd.text("\("相差".languageString())  ")
            lab_tips.cd.isHidden(false)
            btn_sign.cd.text("确认到达".languageString())
            lab_goOff.cd.text("\("出发时间".languageString())：\(data.startOffTime)")
        default:
            break
        }
        lab_arrivalPoint.cd.text("\("到达地点".languageString())：\(data.userAddress)")
        lab_departurePoint.cd.text("\("出发地点".languageString())：\(data.startOffLocation)")
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        if !data.lat.isEmpty && !data.lnt.isEmpty && data.notMaintainedAK != 1 {
            configLocationManager()
            
            let p = AMapGeoPoint()
            p.latitude = self.data.lat.floatValue()
            p.longitude = self.data.lnt.floatValue()
            self.destination = p
            
            self.makeUI()
            
        }else{
            hud_info("lat暂无数据".languageString())
        }
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
    }
    
    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()
        infoView.makeRadius(value: 10, type: [.topLeft, .topRight])
    }
    
    func configLocationManager() {
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
        locationManager.pausesLocationUpdatesAutomatically = false
        locationManager.allowsBackgroundLocationUpdates = true
        locationManager.locationTimeout = 10
        locationManager.reGeocodeTimeout = 10
    }
    
    func makeUI() {
        mapView.frame = mapBgView.bounds
        mapBgView.addSubview(mapView)
//        mapView.snp.makeConstraints { make in
//            make.top.left.bottom.right.equalToSuperview()
//        }
        mapView.delegate = self
        mapView.showsUserLocation = true
        mapView.userTrackingMode = .follow
        if #available(iOS 13.0, *) {
            mapView.showsLargeContentViewer = true
        } else {
            // Fallback on earlier versions
        }
//        search!.delegate = self
        
        geocodeSearch()
    }
    
    func routeSearch()  {
        let navi = AMapDrivingCalRouteSearchRequest()
        navi.showFieldType = .polyline
//        let navi = AMapRidingRouteSearchRequest()
//        navi.showFieldsType = .polyline
        /* 出发点. */
        navi.origin = AMapGeoPoint.location(withLatitude: curLocation.coordinate.latitude, longitude: curLocation.coordinate.longitude)
        /* 目的地. */
        navi.destination = AMapGeoPoint.location(withLatitude: destination.latitude, longitude: destination.longitude)
        self.search?.aMapDrivingV2RouteSearch(navi)
//        search?.aMapRidingRouteSearch(navi)
    }
    
    func geocodeSearch() {
        guard !data.userAddress.isEmpty else { return }
        let geo = AMapGeocodeSearchRequest()
        geo.address = data.userAddress
        self.search?.delegate = self
        self.search?.aMapGeocodeSearch(geo)
    }
    
    func distanceSearch() {
        let request = AMapDistanceSearchRequest()
        request.origins = [AMapGeoPoint.location(withLatitude: curLocation.coordinate.latitude, longitude: curLocation.coordinate.longitude)]
        request.destination = destination
        request.type = .drive
        self.search?.aMapDistanceSearch(request)
    }
    
    func setPointAnnotation()  {
        let pointAnnotation = MAPointAnnotation()
        pointAnnotation.coordinate = CLLocationCoordinate2DMake(destination.latitude, destination.longitude)
        pointAnnotation.title = "终"
        mapView.addAnnotation(pointAnnotation)
    }
    
    @IBAction func sign(_ sender: UIButton) {
        request()
    }
}

extension OrderMapDistanceVc: AMapSearchDelegate, MAMapViewDelegate, AMapLocationManagerDelegate {
    func onRouteSearchDone(_ request: AMapRouteSearchBaseRequest!, response: AMapRouteSearchResponse!) {
        
        guard response.route != nil else {
            return
        }
        
        if response.count > 0 {
            if let path = response.route.paths.first {
                mapView.remove(polyLine)
                polyLine = self.polylinesForPath(path)
                mapView.add(polyLine)
                distanceSearch()
                let lat = (curLocation.coordinate.latitude + destination.latitude)/2
                let lon = (curLocation.coordinate.longitude + destination.longitude)/2
                mapView.centerCoordinate = CLLocationCoordinate2D(latitude: lat, longitude: lon)
                mapView.isShowsLabels = true
                
                let point1 = MAMapPointForCoordinate(curLocation.coordinate);
                let point2 = MAMapPointForCoordinate(CLLocationCoordinate2D(latitude: destination.latitude, longitude: destination.longitude));
                let distance = MAMetersBetweenMapPoints(point1, point2)
                mapView.region = MACoordinateRegionMakeWithDistance(CLLocationCoordinate2D(latitude: lat, longitude: lon), distance, distance)
                setPointAnnotation()
            }
        }
    }
    
//    func onGeocodeSearchDone(_ request: AMapGeocodeSearchRequest!, response: AMapGeocodeSearchResponse!) {
//        if let location = response.geocodes.first?.location {
//            if !data.lat.isEmpty && !data.lnt.isEmpty {
//                let p = AMapGeoPoint()
//                p.latitude = data.lat.floatValue()
//                p.longitude = data.lnt.floatValue()
//                destination = p
//            }else{
//                destination = location
//            }
//            if curLocation.coordinate.latitude > 0, curLocation.coordinate.longitude > 0 {
//                routeSearch()
//            }
//            setPointAnnotation()
//        }
//    }
    
    func onDistanceSearchDone(_ request: AMapDistanceSearchRequest!, response: AMapDistanceSearchResponse!) {
        if let distance = response.results.first?.distance {
            if distance < 1000 {
                lab_distance.cd.text("\(distance)")
                lab_unit.cd.text(" \("米".languageString())")
            }else{
                let km = CGFloat(distance)/1000.0
                lab_distance.cd.text(String(format: "%.1f", km))
                lab_unit.cd.text(" \("公里".languageString())")
            }
        }
    }
    
    func aMapSearchRequest(_ request: Any!, didFailWithError error: Error!) {
        print("error=",error.localizedDescription)
    }
    
    func mapView(_ mapView: MAMapView!, rendererFor overlay: MAOverlay!) -> MAOverlayRenderer! {
        if let tempOver = overlay as? MAPolyline {
            let polygonView = MAPolylineRenderer.init(polyline: tempOver)
            // 参数设置
            polygonView?.lineWidth = 16.0
            polygonView?.strokeColor = Config.color.hex("#478BFF")
//            polygonView?.fillColor = .red
            polygonView?.lineJoinType = kMALineJoinRound
            polygonView?.lineCapType = kMALineCapRound
            polygonView?.strokeImage = UIImage(named: "custtexture")
            return polygonView
        }
        return nil
    }
    
    func mapView(_ mapView: MAMapView!, didUpdate userLocation: MAUserLocation!, updatingLocation: Bool) {
        if showType == 1 && !data.startOffLat.isEmpty && !data.startOffLnt.isEmpty {
            curLocation = CLLocation(latitude: data.startOffLat.doubleValue(), longitude: data.startOffLnt.doubleValue())
        }else if let location = userLocation.location {
            curLocation = location
        }
        getAddress(location: curLocation)
        if destination.latitude > 0, destination.longitude > 0 {
            routeSearch()
        }
    }
    
    func mapView(_ mapView: MAMapView!, viewFor annotation: MAAnnotation!) -> MAAnnotationView! {
        if annotation.isKind(of: MAPointAnnotation.self), annotation.coordinate.latitude != curLocation.coordinate.latitude, annotation.coordinate.longitude != curLocation.coordinate.longitude {
            let pointReuseIndentifier = "pointReuseIndentifier"
            var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: pointReuseIndentifier) as? MAPinAnnotationView
            if annotationView == nil {
                annotationView = MAPinAnnotationView(annotation: annotation, reuseIdentifier: pointReuseIndentifier)
            }
            annotationView?.canShowCallout = false       //设置气泡可以弹出，默认为NO
            annotationView?.animatesDrop = false        //设置标注动画显示，默认为NO
            annotationView?.isDraggable = false       //设置标注可以拖动，默认为NO
            annotationView?.pinColor = .red
            annotationView?.image = UIImage(named: "endPoint")
            return annotationView
        }
        return nil
    }
    
    func amapLocationManager(_ manager: AMapLocationManager!, doRequireLocationAuth locationManager: CLLocationManager!) {
        locationManager.requestAlwaysAuthorization()
    }
    
    func amapLocationManager(_ manager: AMapLocationManager!, didUpdate location: CLLocation!, reGeocode: AMapLocationReGeocode!) {
        
    }
    
    func amapLocationManager(_ manager: AMapLocationManager!, didFailWithError error: Error!) {
        print("error==",error.localizedDescription)
    }
    
    func amapLocationManager(_ manager: AMapLocationManager!, didChange status: CLAuthorizationStatus) {
        if [.authorizedWhenInUse, .notDetermined, .authorizedAlways].contains(status) {
            isOpenLocation = true
        }else if status == .denied {
            isOpenLocation = false
        }else{
            isOpenLocation = false
        }
        if !isOpenLocation {
            showLocationTips()
        }
    }
    
    func amapLocationManager(_ manager: AMapLocationManager!, locationManagerDidChangeAuthorization locationManager: CLLocationManager!) {
        if [.authorizedWhenInUse, .notDetermined, .authorizedAlways].contains(CLLocationManager.authorizationStatus()) {
            isOpenLocation = true
        }else if CLLocationManager.authorizationStatus() == .denied {
            isOpenLocation = false
        }else{
            isOpenLocation = false
        }
        if !isOpenLocation {
            showLocationTips()
        }
    }
    
    func showLocationTips() {
        let alertC = UIAlertController(title: "提示".languageString(), message: "您还未开启定位服务，请前往设置开启，以便于准确获取您的位置信息".languageString(), preferredStyle: .alert)
        alertC.addAction(UIAlertAction(title: "取消".languageString(), style: .default))
        alertC.addAction(UIAlertAction(title: "确定".languageString(), style: .default) {(_) in
            if #available(iOS 10.0, *) {
                UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!, options: [:], completionHandler: nil)
            } else {
                UIApplication.shared.openURL(URL(string: UIApplication.openSettingsURLString)!)
            }
        })
        self.present(alertC, animated: true, completion: nil)
    }
}

extension OrderMapDistanceVc {
    func polylinesForPath(_ path:AMapPath) -> MAPolyline {
//        if path == nil || path.steps.count == 0{
//            return nil
//        }
        
        var polylineMutableString = ""
        for step in path.steps {
            polylineMutableString += String(format: "%@;", step.polyline)
        }

        var coordinates = self.coordinates(forString: polylineMutableString, parseToken: ";")
        let polyline = MAPolyline(coordinates: &coordinates.0, count: UInt(coordinates.1)) ?? MAPolyline()
//        free(&coordinates.0)
        return polyline
    }
    
    func coordinates(forString string:String,parseToken token:String) -> ([CLLocationCoordinate2D], Int) {
        if string.isEmpty {
            return ([], 0)
        }
        
        var token = token
        if token.isEmpty {
            token = ","
        }
        
        var str = ""
        if token != ","{
            str = string.replacingOccurrences(of: token, with: ",")
        }else{
            str = string
        }
        
        let components = str.components(separatedBy: ",")
        let count = components.count/2
        var coordinates:[CLLocationCoordinate2D] = []
        for i in 0..<count {
            var coordinate = CLLocationCoordinate2D()
            coordinate.longitude = components[2*i].doubleValue()
            coordinate.latitude = components[2*i + 1].doubleValue()
            coordinates.append(coordinate)
        }
        return (coordinates, count)
    }
    
    func getAddress(location: CLLocation) {
        let geocoder = CLGeocoder()
        
//        let latitude = location.coordinate.latitude
//        let longitude = location.coordinate.longitude
        
        geocoder.reverseGeocodeLocation(location) { (placemarks, error) in
            if error != nil {
                return
            }
            
            if let place = placemarks?[0]{
                // 国家 省  市  区  街道  名称  国家编码  邮编
                //                let country = place.country ?? ""
                let name = place.name ?? ""
                let thoroughfare = place.thoroughfare ?? ""
                let subThoroughfare = place.subThoroughfare ?? ""
                let administrativeArea = place.administrativeArea ?? ""
                let locality = place.locality ?? ""
                let subLocality = place.subLocality ?? ""
                let subAdministrativeArea = place.subAdministrativeArea ?? ""
                let postalCode = place.postalCode ?? ""
                let isoCountryCode = place.isoCountryCode ?? ""
                let country = place.country ?? ""
                let inlandWater = place.inlandWater ?? ""
                let ocean = place.ocean ?? ""
                let areasOfInterest = place.areasOfInterest ?? [""]
                
                self.curAddress =  administrativeArea + locality + subLocality + thoroughfare + name
                print("****************************")
                let ss = "\(subThoroughfare),\(subAdministrativeArea),\(postalCode),\(isoCountryCode),\(country),\(inlandWater),\(ocean),\(areasOfInterest)"
                print(self.curAddress)
                print(ss)
                if self.showType == 1 && self.data.startOffLocation.isEmpty {
                    self.data.startOffLocation = self.curAddress
                    self.lab_departurePoint.cd.text("\("出发地点".languageString())：\(self.data.startOffLocation)")
                }
            } else {
            }
        }
        
    }
}

extension OrderMapDistanceVc {
    func request() {
        var par:[String:Any] = [:]
        par["orderId"] = orderId
        var urlStr = ""
        switch showType {
        case 1:
            urlStr = "/app/v2/orderDo/startOff"
            par["startOffLocation"] = data.startOffLocation
        case 2:
            urlStr = "/app/v2/orderDo/arrive"
            par["onDoorLocation"] = curAddress
        default:
            break
        }
        SVProgressHUD.show()
        let cNet = TWOCNetwork(url: urlStr,andParam: par)
        cNet.successCall = { [weak self] (result) in
            SVProgressHUD.dismiss()
            guard let weakSelf = self else { return }
            weakSelf.callback?(true)
            hud_succeed("操作成功~")
            CD.pop()
        }
        cNet.failCall = {(errorTag,errorStr) in
            SVProgressHUD.dismiss()
            hud_error(errorStr)
        }
        cNet.postRequest()
    }
}
