import React, { useState, useEffect, useRef } from "react";
import { X, MapPin, Save, Search } from "lucide-react";
import { CustomerAddress, customerService } from "../../src/services/customer.service";

interface AddressFormModalProps {
  isOpen: boolean;
  customerId: number | null;
  address?: CustomerAddress | null;
  onClose: () => void;
  onSave: (address: CustomerAddress) => void;
}

declare global {
  interface Window {
    google: any;
    initMap: () => void;
  }
}

const AddressFormModal: React.FC<AddressFormModalProps> = ({
  isOpen,
  customerId,
  address,
  onClose,
  onSave,
}) => {
  const [formData, setFormData] = useState({
    zipCode: "",
    address: "",
    number: "",
    complement: "",
    neighborhood: "",
    city: "",
    state: "",
    referencePoint: "",
    note: "",
    addressType: "Casa",
    isPrimary: false,
  });

  const [errors, setErrors] = useState<Record<string, string>>({});
  const [isLoading, setIsLoading] = useState(false);
  const [mapLoaded, setMapLoaded] = useState(false);
  const [map, setMap] = useState<any>(null);
  const [marker, setMarker] = useState<any>(null);
  const [geocoder, setGeocoder] = useState<any>(null);
  const mapRef = useRef<HTMLDivElement>(null);
  const [coordinates, setCoordinates] = useState<{ lat: number; lng: number } | null>(null);

  useEffect(() => {
    if (isOpen) {
      if (address) {
        setFormData({
          zipCode: address.zipCode || "",
          address: address.address || "",
          number: address.number || "",
          complement: address.complement || "",
          neighborhood: address.neighborhood || "",
          city: address.city || "",
          state: address.state || "",
          referencePoint: address.referencePoint || "",
          note: address.note || "",
          addressType: address.addressType || "Casa",
          isPrimary: address.isPrimary || false,
        });
        if (address.latitude && address.longitude) {
          setCoordinates({ lat: address.latitude, lng: address.longitude });
        }
      } else {
        setFormData({
          zipCode: "",
          address: "",
          number: "",
          complement: "",
          neighborhood: "",
          city: "",
          state: "",
          referencePoint: "",
          note: "",
          addressType: "Casa",
          isPrimary: false,
        });
        setCoordinates(null);
      }
      loadGoogleMaps();
    }
  }, [isOpen, address]);

  const loadGoogleMaps = () => {
    if (window.google && window.google.maps) {
      initializeMap();
      return;
    }

    if (!document.querySelector('script[src*="maps.googleapis.com"]')) {
      const script = document.createElement("script");
      const apiKey = import.meta.env.VITE_GOOGLE_MAPS_API_KEY || "";
      if (apiKey) {
        script.src = `https://maps.googleapis.com/maps/api/js?key=${apiKey}&libraries=places&callback=initMap`;
        script.async = true;
        script.defer = true;
        window.initMap = initializeMap;
        document.head.appendChild(script);
      } else {
        console.warn("Google Maps API Key não configurada. Configure VITE_GOOGLE_MAPS_API_KEY no arquivo .env");
      }
    } else {
      initializeMap();
    }
  };

  const initializeMap = () => {
    if (!mapRef.current || !window.google) return;

    const initialCenter = coordinates || { lat: -23.5505, lng: -46.6333 }; // São Paulo default

    const mapInstance = new window.google.maps.Map(mapRef.current, {
      center: initialCenter,
      zoom: coordinates ? 15 : 10,
      mapTypeControl: false,
      streetViewControl: false,
      fullscreenControl: false,
    });

    const geocoderInstance = new window.google.maps.Geocoder();
    setGeocoder(geocoderInstance);
    setMap(mapInstance);

    let markerInstance: any = null;

    if (coordinates) {
      markerInstance = new window.google.maps.Marker({
        position: coordinates,
        map: mapInstance,
        draggable: true,
        animation: window.google.maps.Animation.DROP,
      });

      markerInstance.addListener("dragend", (e: any) => {
        const newPosition = {
          lat: e.latLng.lat(),
          lng: e.latLng.lng(),
        };
        setCoordinates(newPosition);
        reverseGeocode(newPosition);
      });
    } else {
      // Adiciona marcador no centro inicial
      markerInstance = new window.google.maps.Marker({
        position: initialCenter,
        map: mapInstance,
        draggable: true,
        animation: window.google.maps.Animation.DROP,
      });

      markerInstance.addListener("dragend", (e: any) => {
        const newPosition = {
          lat: e.latLng.lat(),
          lng: e.latLng.lng(),
        };
        setCoordinates(newPosition);
        reverseGeocode(newPosition);
      });
    }

    setMarker(markerInstance);

    // Click no mapa para adicionar/mover marcador
    mapInstance.addListener("click", (e: any) => {
      const newPosition = {
        lat: e.latLng.lat(),
        lng: e.latLng.lng(),
      };
      setCoordinates(newPosition);

      if (markerInstance) {
        markerInstance.setPosition(newPosition);
      } else {
        markerInstance = new window.google.maps.Marker({
          position: newPosition,
          map: mapInstance,
          draggable: true,
        });
        markerInstance.addListener("dragend", (e: any) => {
          const newPos = {
            lat: e.latLng.lat(),
            lng: e.latLng.lng(),
          };
          setCoordinates(newPos);
          reverseGeocode(newPos);
        });
        setMarker(markerInstance);
      }

      reverseGeocode(newPosition);
    });

    // Autocomplete para busca de endereço
    const autocomplete = new window.google.maps.places.Autocomplete(
      document.getElementById("address-search") as HTMLInputElement,
      { types: ["address"] }
    );

    autocomplete.addListener("place_changed", () => {
      const place = autocomplete.getPlace();
      if (place.geometry) {
        const location = place.geometry.location;
        const newPosition = {
          lat: location.lat(),
          lng: location.lng(),
        };
        setCoordinates(newPosition);
        mapInstance.setCenter(newPosition);
        mapInstance.setZoom(15);

        if (markerInstance) {
          markerInstance.setPosition(newPosition);
        }

        // Preencher campos do formulário
        const addressComponents = place.address_components || [];
        addressComponents.forEach((component: any) => {
          const type = component.types[0];
          if (type === "street_number") {
            setFormData((prev) => ({ ...prev, number: component.long_name }));
          } else if (type === "route") {
            setFormData((prev) => ({ ...prev, address: component.long_name }));
          } else if (type === "sublocality_level_1" || type === "neighborhood") {
            setFormData((prev) => ({ ...prev, neighborhood: component.long_name }));
          } else if (type === "locality") {
            setFormData((prev) => ({ ...prev, city: component.long_name }));
          } else if (type === "administrative_area_level_1") {
            setFormData((prev) => ({ ...prev, state: component.short_name }));
          } else if (type === "postal_code") {
            setFormData((prev) => ({ ...prev, zipCode: component.long_name }));
          }
        });

        if (place.formatted_address) {
          setFormData((prev) => ({ ...prev, address: place.formatted_address.split(",")[0] }));
        }
      }
    });

    setMapLoaded(true);
  };

  const reverseGeocode = (position: { lat: number; lng: number }) => {
    if (!geocoder) return;

    geocoder.geocode({ location: position }, (results: any[], status: string) => {
      if (status === "OK" && results[0]) {
        const result = results[0];
        const addressComponents = result.address_components || [];
        
        addressComponents.forEach((component: any) => {
          const type = component.types[0];
          if (type === "street_number") {
            setFormData((prev) => ({ ...prev, number: component.long_name }));
          } else if (type === "route") {
            setFormData((prev) => ({ ...prev, address: component.long_name }));
          } else if (type === "sublocality_level_1" || type === "neighborhood") {
            setFormData((prev) => ({ ...prev, neighborhood: component.long_name }));
          } else if (type === "locality") {
            setFormData((prev) => ({ ...prev, city: component.long_name }));
          } else if (type === "administrative_area_level_1") {
            setFormData((prev) => ({ ...prev, state: component.short_name }));
          } else if (type === "postal_code") {
            setFormData((prev) => ({ ...prev, zipCode: component.long_name }));
          }
        });
      }
    });
  };

  const handleSearchByCEP = async () => {
    if (!formData.zipCode || formData.zipCode.length < 8) return;

    const cep = formData.zipCode.replace(/\D/g, "");
    if (cep.length !== 8) return;

    try {
      const response = await fetch(`https://viacep.com.br/ws/${cep}/json/`);
      const data = await response.json();

      if (!data.erro) {
        setFormData((prev) => ({
          ...prev,
          address: data.logradouro || "",
          neighborhood: data.bairro || "",
          city: data.localidade || "",
          state: data.uf || "",
        }));

        // Geocodificar o endereço completo
        if (geocoder && data.logradouro) {
          const fullAddress = `${data.logradouro}, ${data.localidade}, ${data.uf}, Brasil`;
          geocoder.geocode({ address: fullAddress }, (results: any[], status: string) => {
            if (status === "OK" && results[0]) {
              const location = results[0].geometry.location;
              const newPosition = {
                lat: location.lat(),
                lng: location.lng(),
              };
              setCoordinates(newPosition);
              if (map) {
                map.setCenter(newPosition);
                map.setZoom(15);
              }
              if (marker) {
                marker.setPosition(newPosition);
              } else if (map) {
                const newMarker = new window.google.maps.Marker({
                  position: newPosition,
                  map: map,
                  draggable: true,
                });
                newMarker.addListener("dragend", (e: any) => {
                  const newPos = {
                    lat: e.latLng.lat(),
                    lng: e.latLng.lng(),
                  };
                  setCoordinates(newPos);
                  reverseGeocode(newPos);
                });
                setMarker(newMarker);
              }
            }
          });
        }
      }
    } catch (error) {
      console.error("Erro ao buscar CEP:", error);
    }
  };

  const handleChange = (field: string, value: string | boolean) => {
    setFormData((prev) => ({ ...prev, [field]: value }));
    if (errors[field]) {
      setErrors((prev) => {
        const newErrors = { ...prev };
        delete newErrors[field];
        return newErrors;
      });
    }
  };

  const validate = () => {
    const newErrors: Record<string, string> = {};

    if (!formData.zipCode) newErrors.zipCode = "CEP é obrigatório";
    if (!formData.address) newErrors.address = "Endereço é obrigatório";
    if (!formData.number) newErrors.number = "Número é obrigatório";
    if (!formData.city) newErrors.city = "Cidade é obrigatória";
    if (!formData.state) newErrors.state = "Estado é obrigatório";

    setErrors(newErrors);
    return Object.keys(newErrors).length === 0;
  };

  const handleSave = async () => {
    if (!validate() || !customerId) return;

    setIsLoading(true);
    try {
      const addressData: Partial<CustomerAddress> = {
        ...formData,
        latitude: coordinates?.lat,
        longitude: coordinates?.lng,
      };

      let savedAddress: CustomerAddress | null;
      if (address?.id) {
        // Atualizar endereço existente
        // TODO: Implementar updateAddress no service
        savedAddress = await customerService.createAddress(customerId, addressData);
      } else {
        // Criar novo endereço
        savedAddress = await customerService.createAddress(customerId, addressData);
      }

      if (savedAddress) {
        onSave(savedAddress);
        onClose();
      }
    } catch (error: any) {
      console.error("Erro ao salvar endereço:", error);
      setErrors({ general: error.message || "Erro ao salvar endereço" });
    } finally {
      setIsLoading(false);
    }
  };

  if (!isOpen) return null;

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm">
      <div className="bg-white rounded-3xl shadow-2xl w-full max-w-6xl max-h-[90vh] flex flex-col overflow-hidden">
        {/* Header */}
        <div className="p-6 bg-[#002147] text-white rounded-t-3xl relative overflow-hidden flex-shrink-0">
          <div className="relative z-10 flex items-center justify-between">
            <div className="flex items-center gap-3">
              <div className="w-12 h-12 bg-orange-500/20 rounded-2xl flex items-center justify-center">
                <MapPin className="w-6 h-6 text-orange-400" />
              </div>
              <div>
                <h3 className="text-xl font-black">
                  {address ? "Editar Endereço" : "Cadastrar Novo Endereço"}
                </h3>
                <p className="text-xs text-orange-400 font-bold uppercase tracking-wider mt-0.5">
                  {address ? "Atualize os dados do endereço" : "Preencha os dados e selecione no mapa"}
                </p>
              </div>
            </div>
            <button
              onClick={onClose}
              className="w-10 h-10 flex items-center justify-center rounded-xl hover:bg-white/10 transition-colors"
            >
              <X className="w-5 h-5" />
            </button>
          </div>
          <div className="absolute right-[-10%] top-[-10%] w-32 h-32 bg-orange-400/10 rounded-full blur-2xl"></div>
        </div>

        {/* Content */}
        <div className="flex-1 overflow-auto p-6">
          <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
            {/* Formulário */}
            <div className="space-y-4">
              <h4 className="text-sm font-black uppercase text-slate-600 mb-4">
                Dados do Endereço
              </h4>

              {/* Busca por CEP ou Endereço */}
              <div>
                <label className="block text-xs font-black uppercase text-slate-400 mb-2">
                  Buscar por CEP ou Endereço
                </label>
                <div className="flex gap-2">
                  <input
                    id="address-search"
                    type="text"
                    placeholder="Digite o CEP ou endereço..."
                    className="flex-1 px-4 py-3 bg-white border-2 border-slate-200 rounded-xl font-bold text-slate-700 outline-none focus:border-orange-500 transition-all"
                  />
                  <button
                    onClick={handleSearchByCEP}
                    className="px-4 py-3 bg-[#002147] text-white rounded-xl font-bold hover:bg-[#001a36] transition-colors"
                  >
                    <Search className="w-5 h-5" />
                  </button>
                </div>
              </div>

              <div className="grid grid-cols-2 gap-4">
                <div>
                  <label className="block text-xs font-black uppercase text-slate-400 mb-2">
                    CEP *
                  </label>
                  <input
                    type="text"
                    value={formData.zipCode}
                    onChange={(e) => handleChange("zipCode", e.target.value)}
                    className={`w-full px-4 py-3 bg-slate-50 rounded-xl font-bold text-[#002147] border ${
                      errors.zipCode ? "border-red-500" : "border-slate-200"
                    } focus:outline-none focus:ring-2 focus:ring-orange-500/20`}
                    placeholder="00000-000"
                  />
                  {errors.zipCode && (
                    <p className="text-red-500 text-xs mt-1">{errors.zipCode}</p>
                  )}
                </div>

                <div>
                  <label className="block text-xs font-black uppercase text-slate-400 mb-2">
                    Tipo
                  </label>
                  <select
                    value={formData.addressType}
                    onChange={(e) => handleChange("addressType", e.target.value)}
                    className="w-full px-4 py-3 bg-slate-50 rounded-xl font-bold text-[#002147] border border-slate-200 focus:outline-none focus:ring-2 focus:ring-orange-500/20"
                  >
                    <option value="Casa">Casa</option>
                    <option value="Trabalho">Trabalho</option>
                    <option value="Outro">Outro</option>
                  </select>
                </div>
              </div>

              <div>
                <label className="block text-xs font-black uppercase text-slate-400 mb-2">
                  Endereço *
                </label>
                <input
                  type="text"
                  value={formData.address}
                  onChange={(e) => handleChange("address", e.target.value)}
                  className={`w-full px-4 py-3 bg-slate-50 rounded-xl font-bold text-[#002147] border ${
                    errors.address ? "border-red-500" : "border-slate-200"
                  } focus:outline-none focus:ring-2 focus:ring-orange-500/20`}
                />
                {errors.address && (
                  <p className="text-red-500 text-xs mt-1">{errors.address}</p>
                )}
              </div>

              <div className="grid grid-cols-2 gap-4">
                <div>
                  <label className="block text-xs font-black uppercase text-slate-400 mb-2">
                    Número *
                  </label>
                  <input
                    type="text"
                    value={formData.number}
                    onChange={(e) => handleChange("number", e.target.value)}
                    className={`w-full px-4 py-3 bg-slate-50 rounded-xl font-bold text-[#002147] border ${
                      errors.number ? "border-red-500" : "border-slate-200"
                    } focus:outline-none focus:ring-2 focus:ring-orange-500/20`}
                  />
                  {errors.number && (
                    <p className="text-red-500 text-xs mt-1">{errors.number}</p>
                  )}
                </div>

                <div>
                  <label className="block text-xs font-black uppercase text-slate-400 mb-2">
                    Complemento
                  </label>
                  <input
                    type="text"
                    value={formData.complement}
                    onChange={(e) => handleChange("complement", e.target.value)}
                    className="w-full px-4 py-3 bg-slate-50 rounded-xl font-bold text-[#002147] border border-slate-200 focus:outline-none focus:ring-2 focus:ring-orange-500/20"
                  />
                </div>
              </div>

              <div>
                <label className="block text-xs font-black uppercase text-slate-400 mb-2">
                  Bairro
                </label>
                <input
                  type="text"
                  value={formData.neighborhood}
                  onChange={(e) => handleChange("neighborhood", e.target.value)}
                  className="w-full px-4 py-3 bg-slate-50 rounded-xl font-bold text-[#002147] border border-slate-200 focus:outline-none focus:ring-2 focus:ring-orange-500/20"
                />
              </div>

              <div className="grid grid-cols-2 gap-4">
                <div>
                  <label className="block text-xs font-black uppercase text-slate-400 mb-2">
                    Cidade *
                  </label>
                  <input
                    type="text"
                    value={formData.city}
                    onChange={(e) => handleChange("city", e.target.value)}
                    className={`w-full px-4 py-3 bg-slate-50 rounded-xl font-bold text-[#002147] border ${
                      errors.city ? "border-red-500" : "border-slate-200"
                    } focus:outline-none focus:ring-2 focus:ring-orange-500/20`}
                  />
                  {errors.city && (
                    <p className="text-red-500 text-xs mt-1">{errors.city}</p>
                  )}
                </div>

                <div>
                  <label className="block text-xs font-black uppercase text-slate-400 mb-2">
                    Estado *
                  </label>
                  <input
                    type="text"
                    value={formData.state}
                    onChange={(e) => handleChange("state", e.target.value)}
                    className={`w-full px-4 py-3 bg-slate-50 rounded-xl font-bold text-[#002147] border ${
                      errors.state ? "border-red-500" : "border-slate-200"
                    } focus:outline-none focus:ring-2 focus:ring-orange-500/20`}
                    maxLength={2}
                    placeholder="SP"
                  />
                  {errors.state && (
                    <p className="text-red-500 text-xs mt-1">{errors.state}</p>
                  )}
                </div>
              </div>

              <div>
                <label className="block text-xs font-black uppercase text-slate-400 mb-2">
                  Ponto de Referência
                </label>
                <input
                  type="text"
                  value={formData.referencePoint}
                  onChange={(e) => handleChange("referencePoint", e.target.value)}
                  className="w-full px-4 py-3 bg-slate-50 rounded-xl font-bold text-[#002147] border border-slate-200 focus:outline-none focus:ring-2 focus:ring-orange-500/20"
                />
              </div>

              <div>
                <label className="block text-xs font-black uppercase text-slate-400 mb-2">
                  Observações
                </label>
                <textarea
                  value={formData.note}
                  onChange={(e) => handleChange("note", e.target.value)}
                  rows={3}
                  className="w-full px-4 py-3 bg-slate-50 rounded-xl font-bold text-[#002147] border border-slate-200 focus:outline-none focus:ring-2 focus:ring-orange-500/20 resize-none"
                />
              </div>

              <div className="flex items-center gap-2">
                <input
                  type="checkbox"
                  id="isPrimary"
                  checked={formData.isPrimary}
                  onChange={(e) => handleChange("isPrimary", e.target.checked)}
                  className="w-5 h-5 rounded border-slate-300 text-[#002147] focus:ring-2 focus:ring-orange-500/20"
                />
                <label htmlFor="isPrimary" className="text-sm font-bold text-slate-700">
                  Definir como endereço principal
                </label>
              </div>

              {errors.general && (
                <div className="p-3 bg-red-50 border border-red-200 rounded-xl">
                  <p className="text-red-600 text-sm font-bold">{errors.general}</p>
                </div>
              )}
            </div>

            {/* Mapa */}
            <div>
              <h4 className="text-sm font-black uppercase text-slate-600 mb-4">
                Localização no Mapa
              </h4>
              <div className="relative">
                <div
                  ref={mapRef}
                  className="w-full h-[500px] rounded-2xl border-2 border-slate-200 overflow-hidden"
                />
                {!mapLoaded && (
                  <div className="absolute inset-0 flex items-center justify-center bg-slate-100">
                    <div className="text-center">
                      <div className="w-12 h-12 border-4 border-[#002147] border-t-transparent rounded-full animate-spin mx-auto mb-2"></div>
                      <p className="text-sm font-bold text-slate-600">Carregando mapa...</p>
                    </div>
                  </div>
                )}
                <div className="mt-3 p-3 bg-slate-50 rounded-xl">
                  <p className="text-xs text-slate-600">
                    <strong>Dica:</strong> Clique no mapa ou arraste o marcador para definir a localização exata do endereço.
                  </p>
                </div>
              </div>
            </div>
          </div>
        </div>

        {/* Footer */}
        <div className="p-6 border-t border-slate-200 flex-shrink-0 flex items-center justify-end gap-3">
          <button
            onClick={onClose}
            className="px-6 py-3 rounded-xl font-bold text-slate-700 hover:bg-slate-100 transition-colors"
          >
            Cancelar
          </button>
          <button
            onClick={handleSave}
            disabled={isLoading}
            className="flex items-center gap-2 px-6 py-3 rounded-xl font-black bg-[#002147] text-white hover:bg-[#001a36] transition-all shadow-lg shadow-[#002147]/20 active:scale-95 disabled:opacity-50 disabled:cursor-not-allowed"
          >
            {isLoading ? (
              <>
                <div className="w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin"></div>
                Salvando...
              </>
            ) : (
              <>
                <Save className="w-4 h-4" />
                Salvar Endereço
              </>
            )}
          </button>
        </div>
      </div>
    </div>
  );
};

export default AddressFormModal;

