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

function PublicView({ currentUser, onLoginRequest }) {
  const [searchQuery, setSearchQuery] = useState('');
  const [medicines, setMedicines] = useState([]);
  const [selectedMedicine, setSelectedMedicine] = useState(null);
  const [pharmacies, setPharmacies] = useState([]);
  const [loading, setLoading] = useState(false);
  const [userPosition, setUserPosition] = useState(null);
  const [positionSource, setPositionSource] = useState(null); // 'profile' | 'browser'
  const [sortByDistance, setSortByDistance] = useState(false);
  const [locating, setLocating] = useState(false);
  const [locationError, setLocationError] = useState('');

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

      setLoading(true);
      try {
        const response = await fetch(`/api/medicines/search?q=${encodeURIComponent(searchQuery)}`);
        const data = await response.json();
        setMedicines(data);
      } catch (error) {
        console.error('Error searching medicines:', error);
      } finally {
        setLoading(false);
      }
    };

    const timeoutId = setTimeout(searchMedicines, 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);
      return;
    }
    if (userPosition) {
      setSortByDistance(true);
      return;
    }
    setLocating(true);
    try {
      const pos = await getUserPosition();
      setUserPosition(pos);
      setPositionSource('browser');
      setSortByDistance(true);
    } catch (err) {
      console.error('[location] error', err);
      let msg;
      if (err && typeof err.code === 'number') {
        if (err.code === 1) msg = 'Location permission denied — allow it in your browser settings';
        else if (err.code === 2) msg = 'Location unavailable — check OS location services / WiFi';
        else if (err.code === 3) msg = 'Location request timed out — try again';
        else msg = `Geolocation error (code ${err.code})`;
      } else {
        msg = err && err.message ? err.message : 'Could not get your location';
      }
      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 (
    <>
      <header className="app-header">
        <h1>💊 FarmaFinder</h1>
        <p>Find your medicine at nearby pharmacies</p>
      </header>

      <main className="app-main">
        <SearchBar
          value={searchQuery}
          onChange={setSearchQuery}
          placeholder="Search for a medicine..."
        />

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

        {searchQuery && !selectedMedicine && (
          <MedicineResults
            medicines={medicines}
            onSelect={setSelectedMedicine}
            query={searchQuery}
            currentUser={currentUser}
            onLoginRequest={onLoginRequest}
          />
        )}

        {selectedMedicine && (
          <div className="selected-medicine-section">
            <div className="medicine-info">
              <h2>{selectedMedicine.name}</h2>
              <div className="medicine-details">
                <span><strong>Active Ingredient:</strong> {selectedMedicine.active_ingredient}</span>
                <span><strong>Dosage:</strong> {selectedMedicine.dosage}</span>
                <span><strong>Form:</strong> {selectedMedicine.form}</span>
              </div>
              <button
                className="back-button"
                onClick={() => {
                  setSelectedMedicine(null);
                  setPharmacies([]);
                }}
              >
                ← Back to search
              </button>
            </div>

            {pharmacies.length > 0 && (
              <div className="pharmacy-controls">
                <button
                  className={`sort-distance-button ${sortByDistance ? 'active' : ''}`}
                  onClick={handleSortByDistance}
                  disabled={locating}
                >
                  {locating
                    ? '📍 Locating…'
                    : sortByDistance
                      ? '📍 Sorted by distance · Reset'
                      : hasSavedCoords
                        ? '📍 Sort by your saved location'
                        : '📍 Sort by distance'}
                </button>
                {sortByDistance && positionSource === 'profile' && (
                  <span className="location-source">Using your saved address</span>
                )}
                {locationError && (
                  <span className="location-error">{locationError}</span>
                )}
              </div>
            )}

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

export default PublicView;
