"use client";

import { useState, useCallback, useMemo } from "react";
import { ArrowUpRight, MapPinned, Navigation, Loader2, UserRound } from "lucide-react";
import type { CaptureMethod, GisStatus, StepGisMappingData } from "@/lib/api-types";
import {
  coordinatePairsToPolygon,
  parseGeoJsonPolygon,
  polygonAreaHa,
} from "@/lib/gis-geojson";
import { t, type WizardLocale } from "@/lib/i18n/wizard-labels";

type PolygonMode = "geojson" | "pairs";

interface Props {
  data: Partial<StepGisMappingData>;
  loading: boolean;
  locale?: WizardLocale;
  primaryParcelId?: string;
  declaredAreaHa?: number;
  onSave: (data: StepGisMappingData) => Promise<unknown>;
  onSaveDraft: (data: Partial<StepGisMappingData>) => Promise<unknown>;
}

export default function StepGisMapping({
  data,
  loading,
  locale = "uz",
  primaryParcelId,
  declaredAreaHa = 0,
  onSave,
}: Props) {
  const [lat, setLat] = useState<string>(data?.coordinates?.lat?.toString() ?? "");
  const [lng, setLng] = useState<string>(data?.coordinates?.lng?.toString() ?? "");
  const [accuracyM, setAccuracyM] = useState<string>(
    data?.coordinates?.accuracyM?.toString() ?? "",
  );
  const [parcelId, setParcelId] = useState(data?.parcelId ?? primaryParcelId ?? "");
  const [polygonMode, setPolygonMode] = useState<PolygonMode>("pairs");
  const [polygonInput, setPolygonInput] = useState(
    data?.geoJson ? JSON.stringify(data.geoJson, null, 2) : "",
  );
  const [coordPairs, setCoordPairs] = useState("");
  const [geolocating, setGeolocating] = useState(false);
  const [geoError, setGeoError] = useState("");

  const parsedPolygon = useMemo(() => {
    if (polygonMode === "geojson") return parseGeoJsonPolygon(polygonInput);
    return coordinatePairsToPolygon(coordPairs);
  }, [polygonMode, polygonInput, coordPairs]);

  const derivedAreaHa = parsedPolygon ? polygonAreaHa(parsedPolygon) : null;
  const areaMismatch =
    derivedAreaHa != null &&
    declaredAreaHa > 0 &&
    Math.abs(derivedAreaHa - declaredAreaHa) / declaredAreaHa > 0.2;

  const useCurrentLocation = useCallback(() => {
    if (!navigator.geolocation) {
      setGeoError("Geolocation is not supported by your browser");
      return;
    }

    setGeolocating(true);
    setGeoError("");

    navigator.geolocation.getCurrentPosition(
      (position) => {
        setLat(position.coords.latitude.toFixed(6));
        setLng(position.coords.longitude.toFixed(6));
        if (position.coords.accuracy) {
          setAccuracyM(Math.round(position.coords.accuracy).toString());
        }
        setGeolocating(false);
      },
      (err) => {
        setGeoError(err.message || "Could not determine location");
        setGeolocating(false);
      },
      { enableHighAccuracy: true, timeout: 15000 },
    );
  }, []);

  const hasCoordinates = lat && lng && !isNaN(Number(lat)) && !isNaN(Number(lng));
  const hasPolygon = parsedPolygon != null;

  const savePayload = (agentAssist = false): StepGisMappingData => {
    if (agentAssist) {
      return {
        gisStatus: "agent_pending",
        parcelId: parcelId || primaryParcelId,
        note: "Awaiting field agent GIS visit",
        captureMethod: "agent_assist",
        agentAssistMode: true,
      };
    }
    if (hasPolygon && parsedPolygon) {
      return {
        gisStatus: "polygon_provided",
        parcelId: parcelId || primaryParcelId,
        geoJson: parsedPolygon,
        derivedAreaHa: derivedAreaHa ?? undefined,
        note: areaMismatch
          ? "Polygon area differs from declared land by >20%"
          : "Farmer-provided polygon for SATAI enrichment",
        captureMethod: "map_polygon" as CaptureMethod,
      };
    }
    if (hasCoordinates) {
      return {
        gisStatus: "coordinates_provided" as GisStatus,
        parcelId: parcelId || primaryParcelId,
        coordinates: {
          lat: parseFloat(lat),
          lng: parseFloat(lng),
          ...(accuracyM ? { accuracyM: parseFloat(accuracyM) } : {}),
        },
        note: "Farmer-provided coordinates for SATAI enrichment",
        captureMethod: "gps" as CaptureMethod,
      };
    }
    return {
      gisStatus: "agent_pending",
      parcelId: parcelId || primaryParcelId,
      note: "Awaiting field agent GIS visit",
      captureMethod: "agent_assist",
      agentAssistMode: true,
    };
  };

  const handleContinue = () => onSave(savePayload(false));
  const handleAgentAssist = () => onSave(savePayload(true));

  return (
    <div className="space-y-5">
      <div>
        <h2 className="font-onest text-2xl font-semibold text-ink">{t("gisMapping.title", locale)}</h2>
        <p className="mt-1 font-inter text-sm text-ink-soft">{t("gisMapping.subtitle", locale)}</p>
      </div>

      <div className="rounded-2xl border border-green-deep/15 bg-green-deep/5 p-6 space-y-5">
        <div className="flex items-center gap-3">
          <MapPinned className="w-8 h-8 text-green-deep shrink-0" />
          <div>
            <h3 className="font-onest text-base font-semibold text-ink">{t("gisMapping.coordinates", locale)}</h3>
            <p className="font-inter text-xs text-muted">{t("gisMapping.coordinatesHint", locale)}</p>
          </div>
        </div>

        {primaryParcelId && (
          <div>
            <label htmlFor="parcelId" className="block font-inter text-xs font-medium text-ink/60 mb-1">
              {t("gisMapping.parcelLink", locale)}
            </label>
            <input
              id="parcelId"
              type="text"
              value={parcelId}
              onChange={(e) => setParcelId(e.target.value)}
              className="w-full px-3 py-2.5 rounded-xl border border-border bg-surface font-inter text-sm text-ink focus:outline-none focus:border-green-deep/40 focus:ring-1 focus:ring-green-deep/20"
            />
          </div>
        )}

        <button
          onClick={useCurrentLocation}
          disabled={geolocating}
          type="button"
          className="w-full flex items-center justify-center gap-2 py-3 rounded-xl border border-green-deep/20 bg-surface text-green-deep font-inter text-sm font-medium hover:bg-green-deep/5 transition-colors disabled:opacity-50 cursor-pointer"
        >
          {geolocating ? (
            <>
              <Loader2 className="w-4 h-4 animate-spin" />
              {t("gisMapping.detecting", locale)}
            </>
          ) : (
            <>
              <Navigation className="w-4 h-4" />
              {t("gisMapping.useLocation", locale)}
            </>
          )}
        </button>

        {geoError && <p className="font-inter text-xs text-red-500">{geoError}</p>}

        <div className="grid grid-cols-2 gap-3">
          <div>
            <label htmlFor="gis-lat" className="block font-inter text-xs font-medium text-ink/60 mb-1">
              {t("gisMapping.latitude", locale)}
            </label>
            <input
              id="gis-lat"
              type="text"
              inputMode="decimal"
              placeholder="41.3111"
              value={lat}
              onChange={(e) => setLat(e.target.value)}
              className="w-full px-3 py-2.5 rounded-xl border border-border bg-surface font-inter text-sm text-ink placeholder:text-muted/70 focus:outline-none focus:border-green-deep/40 focus:ring-1 focus:ring-green-deep/20 transition-colors"
            />
          </div>
          <div>
            <label htmlFor="gis-lng" className="block font-inter text-xs font-medium text-ink/60 mb-1">
              {t("gisMapping.longitude", locale)}
            </label>
            <input
              id="gis-lng"
              type="text"
              inputMode="decimal"
              placeholder="69.2797"
              value={lng}
              onChange={(e) => setLng(e.target.value)}
              className="w-full px-3 py-2.5 rounded-xl border border-border bg-surface font-inter text-sm text-ink placeholder:text-muted/70 focus:outline-none focus:border-green-deep/40 focus:ring-1 focus:ring-green-deep/20 transition-colors"
            />
          </div>
        </div>

        {accuracyM && (
          <p className="font-inter text-xs text-ink/60">
            {t("gisMapping.accuracy", locale)}: ±{accuracyM} m
          </p>
        )}

        {hasCoordinates && (
          <p className="font-inter text-xs text-green-deep">{t("gisMapping.captured", locale)}</p>
        )}
      </div>

      <div className="rounded-2xl border border-border bg-surface p-5 space-y-3">
        <h3 className="font-onest text-sm font-semibold text-ink">
          {locale === "ru" ? "Полигон участка (необязательно)" : "Yer uchastkasi poligoni (ixtiyoriy)"}
        </h3>
        <div className="flex gap-2">
          {(["pairs", "geojson"] as const).map((mode) => (
            <button
              key={mode}
              type="button"
              onClick={() => setPolygonMode(mode)}
              className={`px-3 py-1.5 rounded-full text-xs font-inter font-medium cursor-pointer ${
                polygonMode === mode
                  ? "bg-green-deep text-white"
                  : "border border-border text-ink-soft"
              }`}
            >
              {mode === "pairs"
                ? locale === "ru"
                  ? "Координаты"
                  : "Koordinatalar"
                : "GeoJSON"}
            </button>
          ))}
        </div>
        {polygonMode === "geojson" ? (
          <textarea
            rows={5}
            value={polygonInput}
            onChange={(e) => setPolygonInput(e.target.value)}
            placeholder='{"type":"Polygon","coordinates":[[[69.27,41.31],...]]}'
            className="w-full px-3 py-2.5 rounded-xl border border-border font-mono text-xs text-ink focus:outline-none focus:border-green-deep/40"
          />
        ) : (
          <textarea
            rows={5}
            value={coordPairs}
            onChange={(e) => setCoordPairs(e.target.value)}
            placeholder={"41.3111, 69.2797\n41.3120, 69.2805\n41.3115, 69.2810"}
            className="w-full px-3 py-2.5 rounded-xl border border-border font-inter text-xs text-ink focus:outline-none focus:border-green-deep/40"
          />
        )}
        {derivedAreaHa != null && (
          <p className={`font-inter text-xs ${areaMismatch ? "text-amber-700" : "text-ink/60"}`}>
            {locale === "ru" ? "Расчётная площадь" : "Hisoblangan maydon"}: {derivedAreaHa.toFixed(2)} ha
            {declaredAreaHa > 0 && ` / ${declaredAreaHa.toFixed(2)} ha`}
            {areaMismatch && (locale === "ru" ? " — расхождение >20%" : " — >20% farq")}
          </p>
        )}
      </div>

      <button
        onClick={handleContinue}
        disabled={loading}
        className="w-full flex items-center justify-center gap-2 py-3.5 rounded-full bg-green-deep text-white font-inter font-medium text-base hover:bg-green-deep/90 transition-colors disabled:opacity-50 cursor-pointer"
      >
        {loading
          ? t("common.saving", locale)
          : hasPolygon
            ? t("common.saveContinue", locale)
            : hasCoordinates
              ? t("common.saveContinue", locale)
              : t("gisMapping.skipAgent", locale)}
        <ArrowUpRight className="w-4 h-4" />
      </button>

      <button
        type="button"
        onClick={handleAgentAssist}
        disabled={loading}
        className="w-full flex items-center justify-center gap-2 py-3 rounded-xl border border-border text-ink-soft font-inter text-sm hover:bg-surface-elevated cursor-pointer disabled:opacity-50"
      >
        <UserRound className="w-4 h-4" />
        {locale === "ru" ? "Попросить помощь агента" : "Agent yordamini so'rash"}
      </button>
    </div>
  );
}
