'use client';

import { useCallback, useEffect, useState } from 'react';
import { Loader2, LocateFixed, MapPin, Send } from 'lucide-react';
import { AddressMapPicker } from '@/components/addresses/address-map-picker';
import { Button } from '@/components/ui/button';
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { reverseGeocode } from '@/lib/geocoding';

export interface ChatLocationSharePayload {
  latitude: number;
  longitude: number;
  address?: string;
  label?: string;
}

export function ChatLocationShareDialog({
  open,
  sending,
  onOpenChange,
  onSend,
  onLocateError
}: {
  open: boolean;
  sending?: boolean;
  onOpenChange: (open: boolean) => void;
  onSend: (payload: ChatLocationSharePayload) => Promise<void>;
  onLocateError?: (message: string) => void;
}) {
  const [latitude, setLatitude] = useState<number | undefined>();
  const [longitude, setLongitude] = useState<number | undefined>();
  const [address, setAddress] = useState('');
  const [label, setLabel] = useState('');
  const [locating, setLocating] = useState(false);
  const [resolvingAddress, setResolvingAddress] = useState(false);

  const resetState = useCallback(() => {
    setLatitude(undefined);
    setLongitude(undefined);
    setAddress('');
    setLabel('');
    setLocating(false);
    setResolvingAddress(false);
  }, []);

  useEffect(() => {
    if (!open) {
      resetState();
    }
  }, [open, resetState]);

  const handlePick = useCallback(async (lat: number, lng: number) => {
    setLatitude(lat);
    setLongitude(lng);
    setResolvingAddress(true);
    try {
      const parsed = await reverseGeocode(lat, lng);
      if (parsed?.fullAddress) {
        setAddress(parsed.fullAddress);
      }
    } finally {
      setResolvingAddress(false);
    }
  }, []);

  async function handleUseCurrentLocation() {
    if (!navigator.geolocation) return;
    setLocating(true);
    try {
      const position = await new Promise<GeolocationPosition>((resolve, reject) => {
        navigator.geolocation.getCurrentPosition(resolve, reject, {
          enableHighAccuracy: true,
          timeout: 12_000,
          maximumAge: 30_000
        });
      });
      await handlePick(position.coords.latitude, position.coords.longitude);
    } catch {
      // ошибка геолокации обрабатывается на уровне вызывающего через toast
      throw new Error('Не удалось определить текущее местоположение');
    } finally {
      setLocating(false);
    }
  }

  async function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    if (latitude == null || longitude == null) return;
    await onSend({
      latitude,
      longitude,
      address: address.trim() || undefined,
      label: label.trim() || undefined
    });
  }

  const canSend = latitude != null && longitude != null && !sending;

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-[min(92vw,480px)]">
        <DialogHeader>
          <div className="mx-auto mb-2 flex h-12 w-12 items-center justify-center rounded-full bg-[#f4f5f8]">
            <MapPin className="h-6 w-6 text-[#3390ec]" />
          </div>
          <DialogTitle className="text-center">Отправить геопозицию</DialogTitle>
          <p className="text-center text-sm text-[#6b6f7b]">
            Выберите точку на карте или используйте текущее местоположение
          </p>
        </DialogHeader>

        <form onSubmit={(event) => void handleSubmit(event)} className="space-y-3">
          <div className="overflow-hidden rounded-2xl border border-[#dce3ec]">
            <AddressMapPicker latitude={latitude} longitude={longitude} onPick={(lat, lng) => void handlePick(lat, lng)} />
          </div>

          <div className="flex flex-wrap gap-2">
            <Button
              type="button"
              variant="outline"
              className="rounded-xl"
              disabled={locating || sending}
              onClick={() => {
                void handleUseCurrentLocation().catch((error) => {
                  onLocateError?.(error instanceof Error ? error.message : 'Не удалось определить текущее местоположение');
                });
              }}
            >
              {locating ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : <LocateFixed className="mr-2 h-4 w-4" />}
              Моё местоположение
            </Button>
            {resolvingAddress ? (
              <span className="flex items-center text-xs text-[#667085]">
                <Loader2 className="mr-1 h-3.5 w-3.5 animate-spin" />
                Определяем адрес...
              </span>
            ) : null}
          </div>

          <Input
            value={label}
            onChange={(event) => setLabel(event.target.value)}
            placeholder="Подпись (необязательно)"
            className="h-11 rounded-xl"
            disabled={sending}
          />

          <Input
            value={address}
            onChange={(event) => setAddress(event.target.value)}
            placeholder="Адрес"
            className="h-11 rounded-xl"
            disabled={sending || resolvingAddress}
          />

          <Button type="submit" size="lg" className="w-full rounded-[18px]" disabled={!canSend}>
            {sending ? (
              <>
                <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                Отправляем...
              </>
            ) : (
              <>
                <Send className="mr-2 h-4 w-4" />
                Отправить
              </>
            )}
          </Button>
        </form>
      </DialogContent>
    </Dialog>
  );
}
