import Foundation
import Capacitor
import NativeLib
import CoreLocation

@objc(GeocoderPlugin)
public class GeocoderPlugin: CAPPlugin {
    @objc func reverseGeocode(_ call: CAPPluginCall) {
        let options = GeocoderOptions(useLocale: call.getBool("useLocale", true), defaultLocale: call.getString("defaultLocale", ""), maxResults: call.getInt("maxResults", 1))
        
        let lat = call.getDouble("latitude")
        let lng = call.getDouble("longitude")
        
        if let lat = lat, let lng = lng {
            GeocoderService.shared().reverseGeocode(latitude: lat, longitude: lng, options: options) { [weak self] (placemarks, error) in
                if let error = error {
                    call.reject(error.message)
                    return
                }
                if let placemarks = placemarks {
                    call.resolve([
                        "result": self?.parsePlacemarks(placemarks)
                    ])
                    return
                }
                call.reject("No data avaliable")
            }
        } else {
            call.reject("Invalid data")
        }
        
    }
    
    @objc func forwardGeocode(_ call: CAPPluginCall) {
        let options = GeocoderOptions(useLocale: call.getBool("useLocale", true), defaultLocale: call.getString("defaultLocale", ""), maxResults: call.getInt("maxResults", 1))
        
        let address = call.getString("address")
        
        if let address = address {
            GeocoderService.shared().forwardGeocode(addressString: address, options: options) {  [weak self] (placemarks, error) in
                if let error = error {
                    call.reject(error.message)
                    return
                }
                if let placemarks = placemarks {
                    call.resolve([
                        "result": self?.parsePlacemarks(placemarks)
                    ])
                    return
                }
                call.reject("No data avaliable")
            }
        } else {
            call.reject("Invalid data")
        }
    }
    
    
    private func parsePlacemarks(_ placemarks: [CLPlacemark]) -> [[String:Any]] {
        var resultList = [[String:Any]]()
        for placemark in placemarks {
            var latitude = ""
            if let lat = placemark.location?.coordinate.latitude {
                latitude = "\(lat)"
            }
            var longitude = ""
            if let lon = placemark.location?.coordinate.longitude {
                longitude = "\(lon)"
            }
            var place = [String:Any]()
            place["latitude"] = latitude
            place["longitude"] = longitude
            place["countryCode"] = placemark.isoCountryCode ?? ""
            place["countryName"] = placemark.country ?? ""
            place["postalCode"] = placemark.postalCode ?? ""
            place["administrativeArea"] = placemark.administrativeArea ?? ""
            place["subAdministrativeArea"] = placemark.subAdministrativeArea ?? ""
            place["locality"] = placemark.locality ?? ""
            place["subLocality"] = placemark.subLocality ?? ""
            place["thoroughfare"] = placemark.thoroughfare ?? ""
            place["subThoroughfare"] = placemark.subThoroughfare ?? ""
            place["areasOfInterest"] = placemark.areasOfInterest ?? []
            resultList.append(place)
        }
        
        return resultList
    }
}
