import React, { useState, useEffect, useMemo, useCallback } from 'react';
import SearchBar from '../components/SearchBar';
import MedicineResults from '../components/MedicineResults';
import ProductResults from '../components/ProductResults';
import PharmacyList from '../components/PharmacyList';
import PharmacyMap from '../components/PharmacyMap';
import { haversineKm, getUserPosition, hasCachedPosition } from '../utils/geo';
import './SearchView.css';

const suggestions = [
  { name: 'Paracetamol', icon: 'medication', color: 'neutral-1' },
  { name: 'Ibuprofeno', icon: 'pill', color: 'neutral-2' },
  { name: 'Aspirina', icon: 'vaccines', color: 'neutral-3' },
  { name: 'Omeprazol', icon: 'emergency_home', color: 'neutral-4' },
];

function SearchView({ currentUser, onLoginRequest, initialQuery = '', onNavigateToProduct }) {
  const [searchQuery, setSearchQuery] = useState(initialQuery);
  const [medicines, setMedicines] = useState([]);
  const [products, setProducts] = useState([]);
  const [searchMode, setSearchMode] = useState('all');
  const [selectedMedicine, setSelectedMedicine] = useState(null);
  const [pharmacies, setPharmacies] = useState([]);
  const [loading, setLoading] = useState(false);
  const [userPosition, setUserPosition] = useState(null);
  const [positionSource, setPositionSource] = useState(null);
  const [sortByDistance, setSortByDistance] = useState(false);
  const [locating, setLocating] = useState(false);
  const [locationError, setLocationError] = useState('');
  const [recentSearches, setRecentSearches] = useState([]);

  // Precache position on mount — makes first "sort by distance" nearly instant
  useEffect(() => {
    if (hasCachedPosition()) {
      getUserPosition().then(pos => {
        setUserPosition(pos);
      }).catch(() => {});
    }
  }, []);

  // Fetch recent searches when user is logged in
  useEffect(() => {
    if (!currentUser) {
      setRecentSearches([]);
      return;
    }
    fetch('/api/search/recent', { credentials: 'include' })
      .then((r) => r.json())
      .then((data) => setRecentSearches(Array.isArray(data) ? data : []))
      .catch(() => setRecentSearches([]));
  }, [currentUser]);

  const saveToRecent = useCallback((medicine) => {
    if (!currentUser) return;
    fetch('/api/search/recent', {
      method: 'POST',
      credentials: 'include',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ medicine }),
    }).catch(() => {});
    // Update local state immediately
    setRecentSearches((prev) => {
      const filtered = prev.filter((m) => m.id !== medicine.id);
      return [
        {
          id: medicine.id,
          name: medicine.name,
          active_ingredient: medicine.active_ingredient,
          dosage: medicine.dosage,
          form: medicine.form,
          timestamp: Date.now(),
        },
        ...filtered,
      ].slice(0, 5);
    });
  }, [currentUser]);

  useEffect(() => {
    const searchAll = async () => {
      if (searchQuery.trim().length < 2) {
        setMedicines([]);
        setProducts([]);
        setSelectedMedicine(null);
        setPharmacies([]);
        return;
      }
      setLoading(true);
      const query = searchQuery.trim();

      try {
        // Run both searches in parallel for speed
        const [medicinesRes, productsRes] = await Promise.allSettled([
          fetch(`/api/medicines/search?q=${encodeURIComponent(query)}`),
          fetch(`/api/products/search?q=${encodeURIComponent(query)}`),
        ]);

        // Only update if this search is still the current one
        if (query !== searchQuery.trim()) return;

        if (medicinesRes.status === 'fulfilled' && medicinesRes.value.ok) {
          const medicinesData = await medicinesRes.value.json();
          setMedicines(medicinesData);
        }

        if (productsRes.status === 'fulfilled' && productsRes.value.ok) {
          const productsData = await productsRes.value.json();
          setProducts(productsData.results || []);
        }
      } catch (error) {
        console.error('Search error:', error);
      } finally {
        setLoading(false);
      }
    };
    const timeoutId = setTimeout(searchAll, 300);
    return () => clearTimeout(timeoutId);
  }, [searchQuery]);

  useEffect(() => {
    const fetchPharmacies = async () => {
      if (!selectedMedicine) {
        setPharmacies([]);
        return;
      }
      setLoading(true);
      try {
        const response = await fetch(`/api/medicines/${selectedMedicine.id}/pharmacies`);
        const data = await response.json();
        setPharmacies(data);
      } catch (error) {
        console.error('Error fetching pharmacies:', error);
      } finally {
        setLoading(false);
      }
    };
    fetchPharmacies();
  }, [selectedMedicine]);

  const savedLat = currentUser?.latitude;
  const savedLon = currentUser?.longitude;
  const hasSavedCoords = savedLat != null && savedLon != null;

  const handleSortByDistance = async () => {
    if (sortByDistance) {
      setSortByDistance(false);
      return;
    }
    setLocationError('');
    if (hasSavedCoords) {
      setUserPosition({ lat: savedLat, lon: savedLon });
      setPositionSource('profile');
      setSortByDistance(true);
      // Save to search history
      try {
        fetch('/api/search-history', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          credentials: 'include',
          body: JSON.stringify({
            address: currentUser?.address,
            latitude: savedLat,
            longitude: savedLon,
          }),
        });
      } catch (err) {
        console.error('Error saving search history:', err);
      }
      return;
    }
    if (userPosition) {
      setSortByDistance(true);
      setPositionSource('cached');
      return;
    }
    setLocating(true);
    try {
      const pos = await getUserPosition();
      setUserPosition(pos);
      setPositionSource('browser');
      setSortByDistance(true);
      // Save to search history
      try {
        fetch('/api/search-history', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          credentials: 'include',
          body: JSON.stringify({
            address: 'Ubicación actual',
            latitude: pos.lat,
            longitude: pos.lon,
          }),
        });
      } catch (err) {
        console.error('Error saving search history:', err);
      }
    } catch (err) {
      let msg = 'No se pudo obtener tu ubicación';
      if (err && typeof err.code === 'number') {
        if (err.code === 1) msg = 'Permiso de ubicación denegado. Permite el acceso a la ubicación en tu navegador.';
        else if (err.code === 2) msg = 'Ubicación no disponible. Verifica que el GPS esté activado.';
        else if (err.code === 3) msg = 'La ubicación tardó demasiado. Intenta de nuevo o verifica tu conexión.';
      }
      setLocationError(msg);
    } finally {
      setLocating(false);
    }
  };

  const displayedPharmacies = useMemo(() => {
    if (!sortByDistance || !userPosition) return pharmacies;
    return [...pharmacies].sort((a, b) => {
      if (a.latitude == null || a.longitude == null) return 1;
      if (b.latitude == null || b.longitude == null) return -1;
      return (
        haversineKm(userPosition.lat, userPosition.lon, a.latitude, a.longitude) -
        haversineKm(userPosition.lat, userPosition.lon, b.latitude, b.longitude)
      );
    });
  }, [pharmacies, sortByDistance, userPosition]);

  return (
    <div className="search-view">
      <div className="search-content">
        <SearchBar
          value={searchQuery}
          onChange={setSearchQuery}
          placeholder="Escriba el nombre del medicamento"
        />

        {loading && <div className="loading">Buscando...</div>}

        {!searchQuery && !selectedMedicine && (
          <>
            <section className="suggestions-section">
              <h2 className="section-title">Sugerencias</h2>
              <div className="suggestions-grid">
                {suggestions.map((s, i) => (
                  <button
                    key={i}
                    className={`suggestion-btn suggestion-btn--${s.color}`}
                    onClick={() => setSearchQuery(s.name)}
                  >
                    <div className="suggestion-icon">
                      <svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
                        <path d="M4 8h4V4H4v4zm6 12h4v-4h-4v4zm-6 0h4v-4H4v4zm0-6h4v-4H4v4zm6 0h4v-4h-4v4zm6-10v4h4V4h-4zm-6 4h4V4h-4v4zm6 6h4v-4h-4v4zm0 6h4v-4h-4v4z" />
                      </svg>
                    </div>
                    <span className="suggestion-name">{s.name}</span>
                  </button>
                ))}
              </div>
            </section>

            {currentUser && recentSearches.length > 0 && (
              <section className="recent-section">
                <h2 className="section-title">Resultados Recientes</h2>
                <div className="recent-list">
                  {recentSearches.map((r) => (
                    <div
                      key={r.id}
                      className="recent-card"
                      onClick={() => setSelectedMedicine(r)}
                      style={{ cursor: 'pointer' }}
                    >
                      <div className="recent-card-top">
                        <div>
                          <h3 className="recent-name">{r.name}</h3>
                          <p className="recent-detail">
                            {r.dosage && `${r.dosage}`}
                            {r.dosage && r.form && ' \u2022 '}
                            {r.form}
                          </p>
                        </div>
                        {r.active_ingredient && (
                          <span className="recent-tag">{r.active_ingredient}</span>
                        )}
                      </div>
                      <button
                        className="recent-btn"
                        onClick={(e) => {
                          e.stopPropagation();
                          setSelectedMedicine(r);
                        }}
                      >
                        <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                          <circle cx="12" cy="12" r="10" />
                          <polyline points="12 6 12 12 16 14" />
                        </svg>
                        Encontrar cerca
                      </button>
                    </div>
                  ))}
                </div>
              </section>
            )}
          </>
        )}

        {searchQuery && !selectedMedicine && (
          <>
            <div className="filter-tabs">
              <button
                className={`filter-tab ${searchMode === 'all' ? 'filter-tab--active' : ''}`}
                onClick={() => setSearchMode('all')}
              >
                Todos ({medicines.length + products.length})
              </button>
              <button
                className={`filter-tab ${searchMode === 'medicines' ? 'filter-tab--active' : ''}`}
                onClick={() => setSearchMode('medicines')}
              >
                Medicamentos ({medicines.length})
              </button>
              <button
                className={`filter-tab ${searchMode === 'products' ? 'filter-tab--active' : ''}`}
                onClick={() => setSearchMode('products')}
              >
                Parafarmacia ({products.length})
              </button>
            </div>

            {(searchMode === 'all' || searchMode === 'medicines') && (
              <MedicineResults
                medicines={medicines}
                onSelect={(m) => {
                  saveToRecent(m);
                  setSelectedMedicine(m);
                }}
                query={searchQuery}
                currentUser={currentUser}
                onLoginRequest={onLoginRequest}
              />
            )}

            {(searchMode === 'all' || searchMode === 'products') && products.length > 0 && (
              <div className="products-section">
                <h3 className="section-subtitle">Parafarmacia y Bebé</h3>
                <ProductResults
                  products={products}
                  onSelect={(p) => {
                    if (onNavigateToProduct) {
                      onNavigateToProduct(p.source, p.id);
                    } else {
                      window.location.href = `/product/${p.source}/${p.id}`;
                    }
                  }}
                />
              </div>
            )}
          </>
        )}

        {selectedMedicine && (
          <div className="selected-medicine-section">
            <div className="medicine-info">
              <h2>{selectedMedicine.name}</h2>
              <div className="medicine-details">
                <span><strong>Ingrediente Activo:</strong> {selectedMedicine.active_ingredient}</span>
                <span><strong>Dosis:</strong> {selectedMedicine.dosage}</span>
                <span><strong>Forma:</strong> {selectedMedicine.form}</span>
              </div>
              <button
                className="back-button"
                onClick={() => {
                  setSelectedMedicine(null);
                  setPharmacies([]);
                }}
              >
                ← Volver a búsqueda
              </button>
            </div>

            {pharmacies.length > 0 && (
              <div className="pharmacy-controls">
                <button
                  className={`sort-distance-button ${sortByDistance ? 'active' : ''}`}
                  onClick={handleSortByDistance}
                  disabled={locating}
                >
                  {locating
                    ? '📍 Localizando…'
                    : sortByDistance
                      ? '📍 Ordenado por distancia · Reset'
                      : hasSavedCoords
                        ? '📍 Ordenar por ubicación guardada'
                        : '📍 Ordenar por distancia'}
                </button>
                {sortByDistance && positionSource === 'profile' && (
                  <span className="location-source">Usando tu dirección guardada</span>
                )}
                {sortByDistance && positionSource === 'cached' && (
                  <span className="location-source">Usando ubicación reciente</span>
                )}
                {locationError && (
                  <span className="location-error">
                    {locationError}
                    <button className="retry-location-btn" onClick={handleSortByDistance}>
                      Reintentar
                    </button>
                  </span>
                )}
              </div>
            )}

            <PharmacyMap pharmacies={displayedPharmacies} />
            <PharmacyList
              pharmacies={displayedPharmacies}
              loading={loading}
              userPosition={sortByDistance ? userPosition : null}
              medicine={selectedMedicine}
              currentUser={currentUser}
              onLoginRequest={onLoginRequest}
            />
          </div>
        )}
      </div>
    </div>
  );
}

export default SearchView;
