# Standard Library
import json

# Django
from django.contrib.gis.forms import OSMWidget
from django.utils.translation import gettext_lazy as _


class LatLonOpenlayersOSMWidget(OSMWidget):
    """
    A widget that displays an OSM map and two input fields for latitude and
    longitude.
    Updating the point on the map will update the latitude and longitude fields
    and updating the fields will update the point on the map.

    Optional geocoding: when ``geocoder_address_field_ids`` is provided (a dict
    mapping street, postal_code, city, country to DOM element IDs), a
    "Geocode from address" button is shown. Clicking it fetches coordinates
    and updates the map.

    The geocoding provider is configurable via ``geocoder_provider``:
    - "nominatim" (default): OpenStreetMap Nominatim, works worldwide
    - "ign": IGN Géoplateforme (https://geoservices.ign.fr/), optimized for
      French addresses (BAN, BD TOPO®, Parcellaire Express)
    """

    must_display_latlon_fields = True
    default_geocoder_provider = "nominatim"
    default_clear_features_label = _("Delete all Features")
    default_geocoder_button_label = _("Geocode from address")
    default_geocoder_message_timeout = 5000
    default_geocoder_message_please_enter_address = _(
        "Please enter at least one address field."
    )
    default_geocoder_message_searching = _("Searching…")
    default_geocoder_message_coordinates_updated = _("Coordinates updated.")
    default_geocoder_message_no_results = _("No results found for this address.")
    default_geocoder_message_geocoding_failed = _("Geocoding failed: %(error)s")
    default_latitude_field_id = "id_osm_widget_latitude"
    default_longitude_field_id = "id_osm_widget_longitude"
    template_name = "django_osm_widgets/latlon-openlayers-osm.html"

    class Media(OSMWidget.Media):
        css = {"all": ("django_osm_widgets/osm-widget.css",)}
        js = OSMWidget.Media.js + ("django_osm_widgets/LatLonOpenlayersOSMWidget.js",)

    def __init__(self, attrs=None):
        super().__init__(attrs)
        self.attrs["must_display_latlon_fields"] = self.must_display_latlon_fields
        self.attrs["latitude_field_id"] = self.default_latitude_field_id
        self.attrs["longitude_field_id"] = self.default_longitude_field_id
        self.attrs.setdefault("geocoder_provider", self.default_geocoder_provider)
        self.attrs.setdefault("clear_features_label", self.default_clear_features_label)
        self.attrs.setdefault(
            "geocoder_button_label", self.default_geocoder_button_label
        )
        self.attrs.setdefault(
            "geocoder_message_timeout", self.default_geocoder_message_timeout
        )
        self.attrs.setdefault(
            "geocoder_message_please_enter_address",
            self.default_geocoder_message_please_enter_address,
        )
        self.attrs.setdefault(
            "geocoder_message_searching",
            self.default_geocoder_message_searching,
        )
        self.attrs.setdefault(
            "geocoder_message_coordinates_updated",
            self.default_geocoder_message_coordinates_updated,
        )
        self.attrs.setdefault(
            "geocoder_message_no_results",
            self.default_geocoder_message_no_results,
        )
        self.attrs.setdefault(
            "geocoder_message_geocoding_failed",
            self.default_geocoder_message_geocoding_failed,
        )
        if attrs:
            self.attrs.update(attrs)
        # Pass geocoder_address_field_ids as JSON for the template/JS
        geocoder_ids = self.attrs.get("geocoder_address_field_ids")
        if geocoder_ids is not None:
            self.attrs["geocoder_address_field_ids"] = (
                json.dumps(geocoder_ids)
                if isinstance(geocoder_ids, dict)
                else geocoder_ids
            )
