import UIKit
import MapKit

class ViewController: UIViewController, MKMapViewDelegate {
   @IBOutlet weak var mapView: MKMapView!
   var appleCoord: CLLocationCoordinate2D!
   var route: MKRoute?

   override func viewDidLoad() {
      super.viewDidLoad()
      appleCoord = CLLocationCoordinate2D(latitude: 40.7637825011971, longitude: -73.9731328627541)
      let region = MKCoordinateRegion(center: appleCoord, latitudinalMeters: 2000, longitudinalMeters: 2000)
      mapView.setRegion(region, animated: false)
      mapView.delegate = self

      Task(priority: .high) {
         let request = MKLocalSearch.Request()
         request.naturalLanguageQuery = "Coffee"
         request.region = region

         await searchCoffeePlaces(request: request)
      }
   }
   func searchCoffeePlaces(request: MKLocalSearch.Request) async {
      let search = MKLocalSearch(request: request)
      do {
         let results = try await search.start()
         await MainActor.run {
            let items = results.mapItems
            for item in items {
               if let coordinates = item.placemark.location?.coordinate {
                  let annotation = MKPointAnnotation()
                  annotation.coordinate = coordinates
                  annotation.title = item.name
                  annotation.subtitle = item.phoneNumber
                  self.mapView.addAnnotation(annotation)
               }
            }
         }
      } catch {
         print("Error: \(error)")
      }
   }
   func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
      if let destinationCoord = view.annotation?.coordinate {
         let placeOrigin = MKPlacemark(coordinate: appleCoord)
         let origin = MKMapItem(placemark: placeOrigin)
         origin.name = "Apple Store"

         let placeDestination = MKPlacemark(coordinate: destinationCoord)
         let destination = MKMapItem(placemark: placeDestination)
         destination.name = view.annotation?.title!

         let request = MKDirections.Request()
         request.source = origin
         request.destination = destination
         request.transportType = .walking
         request.requestsAlternateRoutes = false

         Task(priority: .high) {
            await calculateRoute(request: request)
         }
      }
   }
   func calculateRoute(request: MKDirections.Request) async {
      let directions = MKDirections(request: request)
      do {
         let results = try await directions.calculate()
         await MainActor.run {
            let routes = results.routes
            if let oldRoute = self.route {
             self.mapView.removeOverlay(oldRoute.polyline)
               self.route = nil
            }
            self.route = routes.first!
            self.mapView.addOverlay(self.route!.polyline, level: .aboveRoads)
         }
      } catch {
         print("Error: \(error)")
      }
   }
   func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
      let render = MKPolylineRenderer(overlay: overlay)
      render.strokeColor = UIColor.red
      return render
   }
}