import React, { useState, useMemo, useEffect } from 'react';
import { useConfigContext } from '../../contexts/ConfigContext';
import MapView from '../map/MapView';
import FilterPanel from '../users/FilterPanel';
import { calculateDistance } from '../../utils/helpers';
import './PublicUserList.css';

const PublicUserList = ({ users, loading }) => {
  const { userTypeLabels } = useConfigContext();
  
  // Load saved location from localStorage on mount
  const savedLocation = localStorage.getItem('userLocation');
  const initialCoords = savedLocation ? JSON.parse(savedLocation) : null;
  
  const [showMap, setShowMap] = useState(true);
  const [showFilters, setShowFilters] = useState(false);
  const [locationStatus, setLocationStatus] = useState(initialCoords ? 'granted' : 'idle');
  const [locationError, setLocationError] = useState('');
  const [coords, setCoords] = useState(initialCoords);
  const [radiusKm, setRadiusKm] = useState(100);
  const [postalCode, setPostalCode] = useState('');
  const [postalSearching, setPostalSearching] = useState(false);
  const [filters, setFilters] = useState({
    type: null,
    sortBy: 'name'
  });

  // Save location to localStorage whenever it changes
  useEffect(() => {
    if (coords) {
      localStorage.setItem('userLocation', JSON.stringify(coords));
    }
  }, [coords]);

  const handleFilterChange = (key, value) => {
    setFilters(prev => ({ ...prev, [key]: value }));
  };

  const requestLocation = () => {
    if (!navigator.geolocation) {
      return;
    }

    setLocationStatus('requesting');
    setLocationError('');

    navigator.geolocation.getCurrentPosition(
      (position) => {
        setCoords({
          lat: position.coords.latitude,
          lng: position.coords.longitude
        });
        setLocationStatus('granted');
      },
      () => {
        setLocationStatus('idle');
      },
      {
        enableHighAccuracy: true,
        timeout: 15000,
        maximumAge: 0
      }
    );
  };

  const searchByPostalCode = async () => {
    if (!postalCode || postalCode.trim().length < 4) {
      setLocationError('Bitte geben Sie eine gültige Postleitzahl ein');
      return;
    }

    setPostalSearching(true);
    setLocationError('');

    try {
      const response = await fetch(
        `https://nominatim.openstreetmap.org/search?postalcode=${encodeURIComponent(postalCode)}&country=Germany&format=json&limit=1`,
        {
          headers: {
            'User-Agent': 'tracking-leaders-app/1.0'
          }
        }
      );

      if (!response.ok) {
        throw new Error('Geocoding fehlgeschlagen');
      }

      const data = await response.json();

      if (data && data.length > 0) {
        setCoords({
          lat: parseFloat(data[0].lat),
          lng: parseFloat(data[0].lon)
        });
        setLocationStatus('granted');
        setLocationError('');
      } else {
        setLocationError('Postleitzahl nicht gefunden');
      }
    } catch (error) {
      setLocationError('Fehler bei der PLZ-Suche');
    } finally {
      setPostalSearching(false);
    }
  };

  const { list: filteredAndSortedUsers, missingGpsCount, allUsersWithGPS } = useMemo(() => {
    let filtered = [...users];

    // Nur verfügbare Nachsuchenführer
    filtered = filtered.filter(user => user.available);

    // Type filter
    if (filters.type) {
      filtered = filtered.filter(user => user.type === filters.type);
    }

    const missingGps = filtered.filter(user => !(user.gps && user.gps.lat && user.gps.lng)).length;
    
    // Alle Benutzer mit GPS für die Karte (vor Radius-Filterung)
    const allWithGPS = filtered.filter(user => user.gps && user.gps.lat && user.gps.lng);

    if (coords) {
      const withDistance = filtered
        .filter(user => user.gps && user.gps.lat && user.gps.lng)
        .map(user => ({
          ...user,
          distanceKm: calculateDistance(
            coords.lat,
            coords.lng,
            user.gps.lat,
            user.gps.lng
          )
        }))
        .filter(user => user.distanceKm <= radiusKm)
        .sort((a, b) => a.distanceKm - b.distanceKm);

      return { list: withDistance, missingGpsCount: missingGps, allUsersWithGPS: allWithGPS };
    }

    // Sort by name/type when no location
    filtered.sort((a, b) => {
      switch (filters.sortBy) {
        case 'nameDesc':
          return b.name.localeCompare(a.name);
        case 'type':
          return a.type.localeCompare(b.type);
        case 'name':
        default:
          return a.name.localeCompare(b.name);
      }
    });

    return { list: filtered, missingGpsCount: missingGps, allUsersWithGPS: allWithGPS };
  }, [users, filters, coords, radiusKm]);

  if (loading) {
    return <div className="loading">Lädt verfügbare Führer...</div>;
  }

  if (!users || users.length === 0) {
    return (
      <div className="no-users">
        <p>Derzeit sind keine Nachsuchenführer verfügbar.</p>
      </div>
    );
  }

  return (
    <div className="public-user-list">
      <div className="list-header">
        <h2>Verfügbare Nachsuchenführer</h2>
        <button
          className="toggle-map-button"
          onClick={() => setShowMap(!showMap)}
        >
          {showMap ? 'Karte ausblenden' : 'Karte anzeigen'}
        </button>
      </div>
      <div className="location-panel">
        <div className="location-controls">
          <button
            className="location-button"
            onClick={requestLocation}
            disabled={locationStatus === 'requesting'}
          >
            {locationStatus === 'requesting' ? 'Wird geladen...' : coords ? 'Standort aktualisieren' : 'Standort freigeben'}
          </button>
          <div className="postal-search">
            <input
              type="text"
              placeholder="oder PLZ eingeben"
              value={postalCode}
              onChange={(e) => setPostalCode(e.target.value)}
              onKeyPress={(e) => e.key === 'Enter' && searchByPostalCode()}
              disabled={postalSearching}
            />
            <button
              onClick={searchByPostalCode}
              disabled={postalSearching || !postalCode}
            >
              {postalSearching ? 'Suche...' : 'Suchen'}
            </button>
          </div>
          {coords && (
            <span className="location-status success">
              Standort aktiv
            </span>
          )}
          {locationError && (
            <span className="location-status error">
              {locationError}
            </span>
          )}
        </div>
        <div className="radius-filter">
          <label htmlFor="radiusKm">Radius (km)</label>
          <div className="radius-inputs">
            <input
              type="range"
              id="radiusKm"
              min="1"
              max="200"
              value={radiusKm}
              onChange={(e) => setRadiusKm(parseInt(e.target.value, 10))}
              disabled={!coords}
            />
            <input
              type="number"
              min="1"
              max="200"
              value={radiusKm}
              onChange={(e) => setRadiusKm(parseInt(e.target.value || '1', 10))}
              disabled={!coords}
            />
          </div>
          <p className="radius-hint">
            Standort wird nur im Browser genutzt und nicht gespeichert.
          </p>
        </div>
        {coords && missingGpsCount > 0 && (
          <div className="gps-hint">
            {missingGpsCount} verfügbare Führer ohne GPS-Daten werden nicht nach Entfernung angezeigt.
          </div>
        )}
      </div>
      <div className="filter-toggle">
        <button
          className="filter-toggle-button"
          onClick={() => setShowFilters(!showFilters)}
        >
          {showFilters ? 'Filter ausblenden' : 'Filter anzeigen'}
        </button>
      </div>
      {showFilters && (
        <FilterPanel
          filters={filters}
          onFilterChange={handleFilterChange}
          showAvailableFilter={false}
        />
      )}
      {showMap && (
        <MapView 
          users={allUsersWithGPS} 
          center={[52.5, 9.5]} 
          zoom={8}
          userLocation={coords}
          radiusKm={radiusKm}
        />
      )}
      {filteredAndSortedUsers.length === 0 ? (
        <div className="no-users">
          <p>Keine Nachsuchenführer im gewählten Radius gefunden.</p>
        </div>
      ) : (
        <div className="user-grid">
          {filteredAndSortedUsers.map(user => (
            <div key={user._id} className="user-card">
              {user.photo && (
                <div className="user-card-photo">
                  <img src={user.photo} alt={user.name} className="user-card-photo-img" />
                </div>
              )}
              <h3 className="user-name">{user.name}</h3>
              <p className="user-role">Nachsuchenführer</p>
              <div className="user-info">
                <p className="user-address">📍 {user.address}</p>
                <a href={`tel:${user.phone}`} className="user-phone">
                  � {user.phone}
                </a>
                {user.landline && (
                  <a href={`tel:${user.landline}`} className="user-phone">
                    📞 {user.landline}
                  </a>
                )}
                <p className="user-type">
                  <span className="type-badge" title={userTypeLabels[user.type]}>{user.type}</span>
                </p>
              </div>
              {user.distanceKm !== undefined && (
                <div className="user-distance">
                  Entfernung: {user.distanceKm.toFixed(1)} km
                </div>
              )}
            </div>
          ))}
        </div>
      )}
    </div>
  );
};

export default PublicUserList;
