"use client";

import * as React from "react";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { t } from "@/lib/i18n/de";
import type { Coordinates } from "@/lib/geo/types";

type StandortInputProps = {
  /** Wird mit den ermittelten Koordinaten (und optionalem Anzeigenamen) aufgerufen. */
  onResolved: (coords: Coordinates, displayName?: string) => void;
  defaultAddress?: string;
};

type State = "idle" | "locating" | "geocoding" | "error";

/**
 * Standort-Eingabe für die Eintreffzeit-Sortierung: entweder Browser-Geolocation
 * („Meinen Standort verwenden") oder eine Adresse, die über `/api/geo/geocode`
 * (auth-gated) geokodiert wird. Reine Client-Komponente; kein direkter Geo-Import,
 * damit die Server-Geo-Module nicht ins Client-Bundle gezogen werden.
 */
export function StandortInput({ onResolved, defaultAddress = "" }: StandortInputProps) {
  const [address, setAddress] = React.useState(defaultAddress);
  const [state, setState] = React.useState<State>("idle");
  const [message, setMessage] = React.useState<string | null>(null);

  const useMyLocation = React.useCallback(() => {
    if (!("geolocation" in navigator)) {
      setState("error");
      setMessage(t("fehler.allgemein"));
      return;
    }
    setState("locating");
    setMessage(null);
    navigator.geolocation.getCurrentPosition(
      (pos) => {
        setState("idle");
        onResolved({ lat: pos.coords.latitude, lng: pos.coords.longitude });
      },
      () => {
        setState("error");
        setMessage(t("fehler.allgemein"));
      },
      { timeout: 8000 },
    );
  }, [onResolved]);

  const geocode = React.useCallback(async () => {
    const value = address.trim();
    if (!value) return;
    setState("geocoding");
    setMessage(null);
    try {
      const res = await fetch("/api/geo/geocode", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ address: value }),
      });
      if (!res.ok) {
        setState("error");
        setMessage(t("search.keineTreffer"));
        return;
      }
      const data = (await res.json()) as {
        coords: Coordinates;
        displayName?: string;
      };
      setState("idle");
      onResolved(data.coords, data.displayName);
    } catch {
      setState("error");
      setMessage(t("fehler.allgemein"));
    }
  }, [address, onResolved]);

  const busy = state === "locating" || state === "geocoding";

  return (
    <div className="flex flex-col gap-2">
      <div className="flex items-center gap-2">
        <Input
          type="text"
          value={address}
          onChange={(e) => setAddress(e.target.value)}
          onKeyDown={(e) => {
            if (e.key === "Enter") {
              e.preventDefault();
              void geocode();
            }
          }}
          placeholder={t("search.adressePlaceholder")}
          aria-label={t("search.adresse")}
          disabled={busy}
        />
        <Button type="button" onClick={() => void geocode()} disabled={busy}>
          {t("search.suchen")}
        </Button>
      </div>
      <Button
        type="button"
        variant="outline"
        onClick={useMyLocation}
        disabled={busy}
      >
        {t("search.meinStandort")}
      </Button>
      {busy ? (
        <p className="text-xs text-anthrazit/60">{t("aktion.laden")}</p>
      ) : null}
      {message ? <p className="text-xs text-wartung">{message}</p> : null}
    </div>
  );
}
