package com.tasapp.capacitor;

import android.Manifest;
import android.location.Address;

import com.getcapacitor.JSArray;
import com.getcapacitor.JSObject;
import com.getcapacitor.Plugin;
import com.getcapacitor.PluginCall;
import com.getcapacitor.PluginMethod;
import com.getcapacitor.annotation.CapacitorPlugin;
import com.getcapacitor.annotation.Permission;
import com.tasapp.android.GeocoderOptions;
import com.tasapp.android.GeocoderService;

import org.json.JSONArray;
import org.json.JSONException;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutionException;

@CapacitorPlugin(
        name = "GeocoderPlugin",
        permissions = { @Permission(strings = { Manifest.permission.INTERNET }, alias = "Internet") })
public class GeocoderPlugin extends Plugin {
        private GeocoderService geocoderService = new GeocoderService();

        @PluginMethod
        public void reverseGeocode(PluginCall call) {
                GeocoderOptions options = new GeocoderOptions(
                        call.getBoolean("useLocale", false),
                        call.getString("defaultLocale", null),
                        call.getInt("maxResults", 1)
                );
                double lat = call.getDouble("latitude");
                double lng = call.getDouble("longitude");

                try {
                        List<Address> result = geocoderService.reverseGeocode(lat, lng, options, getContext());
                        call.resolve(parseResult(result));
                } catch (Exception e) {
                        e.printStackTrace();
                        call.reject(e.getMessage());
                }
        }

        @PluginMethod
        public void forwardGeocode(PluginCall call) {
                GeocoderOptions options = new GeocoderOptions(
                        call.getBoolean("useLocale", false),
                        call.getString("defaultLocale", null),
                        call.getInt("maxResults", 1)
                );
                String address = call.getString("address", null);
                if (address == null) {
                        call.reject("Address string must not be empty");
                        return;
                }

                try {
                        List<Address> result = geocoderService.forwardGeocode(address, options, getContext());
                        call.resolve(parseResult(result));
                } catch (Exception e) {
                        e.printStackTrace();
                        call.reject(e.getMessage());
                }
        }

        private JSObject parseResult(List<Address> addresses) throws JSONException {
                JSObject result = new JSObject();
                JSArray results = new JSArray();
                for(Address address : addresses) {
                        JSObject place = new JSObject();
                        place.put("latitude", !String.valueOf(address.getLatitude()).isEmpty() ? address.getLatitude() : "");
                        place.put("longitude", !String.valueOf(address.getLongitude()).isEmpty() ? address.getLongitude() : "");
                        place.put("countryCode", address.getCountryCode() != null ? address.getCountryCode() : "");
                        place.put("countryName", address.getCountryName() != null ? address.getCountryName() : "");
                        place.put("postalCode", address.getPostalCode() != null ? address.getPostalCode() : "");
                        place.put("administrativeArea", address.getAdminArea() != null ? address.getAdminArea() : "");
                        place.put("subAdministrativeArea", address.getSubAdminArea() != null ? address.getSubAdminArea() : "");
                        place.put("locality", address.getLocality() != null ? address.getLocality() : "");
                        place.put("subLocality", address.getSubLocality() != null ? address.getSubLocality() : "");
                        place.put("thoroughfare", address.getThoroughfare() != null ? address.getThoroughfare() : "");
                        place.put("subThoroughfare", address.getSubThoroughfare() != null ? address.getSubThoroughfare() : "");
                        place.put("areasOfInterest", address.getFeatureName() != null ? new JSONArray(new String[]{ address.getFeatureName()} ) : new JSONArray());

                        results.put(place);
                }
                return result.put("result", results);
        }
}
