// Trouver ma FI — page avec carte Leaflet interactive

const ANGERS_CENTER = [47.4500, -0.5650];

// Format a BAN address feature into a single readable line.
function formatSuggestion(s) {
  return s.properties?.label || "";
}

// Split a BAN address into primary / secondary lines for the dropdown.
function parseSuggestion(s) {
  const p = s.properties || {};
  const primary = p.name || p.label || "";
  const secondary = [p.postcode, p.city].filter(Boolean).join(" ");
  return { primary, secondary };
}

const FindPage = () => {
  const [selectedId, setSelectedId] = React.useState(null);
  const [userPos, setUserPos] = React.useState(null);
  const [addressInput, setAddressInput] = React.useState("");
  const [searchStatus, setSearchStatus] = React.useState("");
  const [geocodeTick, setGeocodeTick] = React.useState(0);
  const [suggestions, setSuggestions] = React.useState([]);
  const [showSuggest, setShowSuggest] = React.useState(false);
  const [highlightIdx, setHighlightIdx] = React.useState(-1);
  const suggestBoxRef = React.useRef(null);
  const mapRef = React.useRef(null);
  const leafletRef = React.useRef({ map: null, circles: {}, userMarker: null });

  // Debounced autocomplete via la Base Adresse Nationale (data.gouv.fr)
  // Biaisée autour d'Angers — bien plus précise que Nominatim pour les adresses françaises.
  React.useEffect(() => {
    const q = addressInput.trim();
    if (q.length < 3) {
      setSuggestions([]);
      setShowSuggest(false);
      return;
    }
    const ctrl = new AbortController();
    const t = setTimeout(async () => {
      try {
        const params = new URLSearchParams({
          q,
          limit: "6",
          autocomplete: "1",
          lat: "47.4784",
          lon: "-0.5632",
        });
        const res = await fetch(`https://api-adresse.data.gouv.fr/search/?${params}`, {
          signal: ctrl.signal,
        });
        const data = await res.json();
        const feats = (data && data.features) || [];
        setSuggestions(feats);
        setShowSuggest(true);
        setHighlightIdx(-1);
      } catch (err) {
        if (err.name !== "AbortError") setSuggestions([]);
      }
    }, 220);
    return () => { clearTimeout(t); ctrl.abort(); };
  }, [addressInput]);

  // Close dropdown on outside click
  React.useEffect(() => {
    const onDown = (e) => {
      if (suggestBoxRef.current && !suggestBoxRef.current.contains(e.target)) {
        setShowSuggest(false);
      }
    };
    document.addEventListener("mousedown", onDown);
    return () => document.removeEventListener("mousedown", onDown);
  }, []);

  const pickSuggestion = (s) => {
    const [lng, lat] = s.geometry.coordinates;
    setUserPos({ lat, lng });
    setAddressInput(formatSuggestion(s));
    setShowSuggest(false);
    setSuggestions([]);
    setSearchStatus("Adresse sélectionnée — voici les FI les plus proches.");
  };

  const onKeyDown = (e) => {
    if (!showSuggest || suggestions.length === 0) return;
    if (e.key === "ArrowDown") {
      e.preventDefault();
      setHighlightIdx((i) => Math.min(suggestions.length - 1, i + 1));
    } else if (e.key === "ArrowUp") {
      e.preventDefault();
      setHighlightIdx((i) => Math.max(0, i - 1));
    } else if (e.key === "Enter" && highlightIdx >= 0) {
      e.preventDefault();
      pickSuggestion(suggestions[highlightIdx]);
    } else if (e.key === "Escape") {
      setShowSuggest(false);
    }
  };

  // FI list, sorted by distance if userPos
  const sortedFI = React.useMemo(() => {
    const list = window.FI_DATA.map((fi) => ({
      ...fi,
      distance: userPos ? window.haversineKm(userPos, fi) : null
    }));
    if (userPos) list.sort((a, b) => a.distance - b.distance);
    return list;
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [userPos, geocodeTick]);

  // Init Leaflet map once
  React.useEffect(() => {
    if (!window.L || !mapRef.current || leafletRef.current.map) return;
    const map = window.L.map(mapRef.current, {
      zoomControl: true,
      attributionControl: true,
      scrollWheelZoom: false
    }).setView(ANGERS_CENTER, 11);

    // Use a softer tile style — Carto Voyager
    window.L.tileLayer("https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png", {
      attribution: '&copy; OpenStreetMap &copy; Carto',
      maxZoom: 18
    }).addTo(map);

    // Add fuzzy circles for each FI (no precise marker — only an approximate zone)
    window.FI_DATA.forEach((fi) => {
      const ring = window.L.circle([fi.lat, fi.lng], {
        radius: fi.radius,
        color: "#D9633A",
        fillColor: "#EE7D4F",
        fillOpacity: 0.22,
        weight: 2,
        opacity: 0.7,
        className: "fi-zone"
      }).addTo(map);

      // Inner small dot at center
      const dot = window.L.circleMarker([fi.lat, fi.lng], {
        radius: 5,
        color: "#FFFFFF",
        weight: 2,
        fillColor: "#D9633A",
        fillOpacity: 1
      }).addTo(map);

      const openDetail = () => setSelectedId(fi.id);
      ring.on("click", openDetail);
      dot.on("click", openDetail);
      ring.bindTooltip(`<strong>${fi.name}</strong><br/><span style="color:#7B786F;font-size:12px">${fi.city}</span>`, {
        direction: "top",
        offset: [0, -8],
        className: "fi-tooltip"
      });

      leafletRef.current.circles[fi.id] = { ring, dot };
    });

    leafletRef.current.map = map;

    // Smooth zoom on container ready
    setTimeout(() => map.invalidateSize(), 100);
  }, []);

  // React to live geocoding — reposition circles as addresses resolve
  React.useEffect(() => {
    const onGeocoded = (e) => {
      const { id, lat, lng } = e.detail;
      const c = leafletRef.current.circles[id];
      if (c) {
        c.ring.setLatLng([lat, lng]);
        c.dot.setLatLng([lat, lng]);
      }
      // Force re-render to refresh distances/sort
      setGeocodeTick((t) => t + 1);
    };
    window.addEventListener("fiGeocoded", onGeocoded);
    return () => window.removeEventListener("fiGeocoded", onGeocoded);
  }, []);

  // Highlight selected on map
  React.useEffect(() => {
    const { circles, map } = leafletRef.current;
    if (!map) return;
    Object.entries(circles).forEach(([id, { ring }]) => {
      if (id === selectedId) {
        ring.setStyle({ fillOpacity: 0.42, weight: 3, opacity: 1 });
      } else {
        ring.setStyle({ fillOpacity: 0.22, weight: 2, opacity: 0.7 });
      }
    });
    if (selectedId) {
      const fi = window.FI_DATA.find((f) => f.id === selectedId);
      if (fi) map.flyTo([fi.lat, fi.lng], 14, { duration: 0.8 });
    }
  }, [selectedId]);

  // Place user marker
  React.useEffect(() => {
    const { map } = leafletRef.current;
    if (!map) return;
    if (leafletRef.current.userMarker) {
      map.removeLayer(leafletRef.current.userMarker);
      leafletRef.current.userMarker = null;
    }
    if (userPos) {
      const icon = window.L.divIcon({
        className: "user-marker",
        html: '<div style="width:18px;height:18px;border-radius:50%;background:#2A2926;border:3px solid #FFFCF6;box-shadow:0 0 0 2px #2A2926, 0 0 20px rgba(42,41,38,0.4)"></div>',
        iconSize: [18, 18],
        iconAnchor: [9, 9]
      });
      const marker = window.L.marker([userPos.lat, userPos.lng], { icon }).addTo(map);
      marker.bindTooltip("Ta position", { direction: "top", offset: [0, -10] });
      leafletRef.current.userMarker = marker;
      map.flyTo([userPos.lat, userPos.lng], 13, { duration: 0.8 });
    }
  }, [userPos]);

  // Geolocate
  const geolocate = () => {
    if (!navigator.geolocation) {
      setSearchStatus("La géolocalisation n'est pas supportée par ton navigateur.");
      return;
    }
    setSearchStatus("Localisation en cours…");
    navigator.geolocation.getCurrentPosition(
      (p) => {
        setUserPos({ lat: p.coords.latitude, lng: p.coords.longitude });
        setSearchStatus("Position trouvée — voici les FI les plus proches.");
      },
      () => {
        // Fallback: simulate a position near Angers center for the demo
        setUserPos({ lat: 47.4784 + (Math.random() - 0.5) * 0.02, lng: -0.5632 + (Math.random() - 0.5) * 0.02 });
        setSearchStatus("Position simulée près du centre d'Angers (la géolocalisation a été refusée).");
      }
    );
  };

  // Address search — uses the Base Adresse Nationale for proper French geocoding
  const searchAddress = async (e) => {
    e.preventDefault();
    if (!addressInput.trim()) return;
    // If a suggestion is highlighted, just pick it
    if (highlightIdx >= 0 && suggestions[highlightIdx]) {
      pickSuggestion(suggestions[highlightIdx]);
      return;
    }
    setSearchStatus("Recherche de l'adresse…");
    try {
      const params = new URLSearchParams({
        q: addressInput,
        limit: "1",
        lat: "47.4784",
        lon: "-0.5632",
      });
      const res = await fetch(`https://api-adresse.data.gouv.fr/search/?${params}`);
      const data = await res.json();
      const feat = data && data.features && data.features[0];
      if (feat) {
        const [lng, lat] = feat.geometry.coordinates;
        setUserPos({ lat, lng });
        setAddressInput(feat.properties.label);
        setSearchStatus("Adresse trouvée — voici les FI les plus proches.");
      } else {
        setSearchStatus("Adresse introuvable. Essaie d'être plus précis (n°, rue, ville).");
      }
    } catch (err) {
      setSearchStatus("Recherche indisponible — réessaie dans un instant.");
    }
  };

  const selected = selectedId ? window.FI_DATA.find((f) => f.id === selectedId) : null;

  return (
    <div className="find-page">
      <div className="container">
        <div className="find-head">
          <h1>Trouve la FI la plus proche de chez toi.</h1>
          <p>
            Entre ton adresse, ou active ta position. Les zones colorées indiquent
            l'emplacement <em>approximatif</em> de chaque FI — l'adresse exacte
            t'est communiquée par WhatsApp quand tu contactes le référent.
          </p>
        </div>

        <div className="search-wrap" ref={suggestBoxRef}>
          <form className="search-bar" onSubmit={searchAddress}>
            <span className="search-bar__icon"><Icon name="search" size={18} /></span>
            <input
              type="text"
              placeholder="Ton adresse à Angers (ex : 5 rue Bressigny)"
              value={addressInput}
              onChange={(e) => setAddressInput(e.target.value)}
              onFocus={() => suggestions.length && setShowSuggest(true)}
              onKeyDown={onKeyDown}
              autoComplete="off"
              spellCheck="false" />
            
            <button type="button" className="search-bar__geo" onClick={geolocate}>
              <Icon name="target" size={16} /> Ma position
            </button>
            <button type="submit" className="btn btn--primary">
              Chercher
            </button>
          </form>
          {showSuggest && suggestions.length > 0 && (
            <ul className="autocomplete">
              {suggestions.map((s, i) => {
                const { primary, secondary } = parseSuggestion(s);
                return (
                  <li
                    key={s.properties?.id || i}
                    className={"autocomplete__item" + (i === highlightIdx ? " autocomplete__item--hl" : "")}
                    onMouseEnter={() => setHighlightIdx(i)}
                    onMouseDown={(e) => { e.preventDefault(); pickSuggestion(s); }}
                  >
                    <span className="autocomplete__icon"><Icon name="pin" size={14} /></span>
                    <span className="autocomplete__text">
                      <strong>{primary}</strong>
                      {secondary && <span>{secondary}</span>}
                    </span>
                  </li>
                );
              })}
            </ul>
          )}
        </div>
        {searchStatus &&
        <div style={{ marginTop: -20, marginBottom: 24, fontSize: 14, color: "var(--ink-soft)", paddingLeft: 16 }}>
            {searchStatus}
          </div>
        }

        <div className="find-layout">
          <div className="fi-list">
            <div className="fi-list__header">
              <h3>{userPos ? "Triées par distance" : "Toutes les FI d'Angers"}</h3>
              <span className="fi-list__count">{sortedFI.length} groupes</span>
            </div>
            {sortedFI.map((fi) =>
            <div
              key={fi.id}
              className={"fi-card" + (selectedId === fi.id ? " fi-card--active" : "")}
              onClick={() => setSelectedId(fi.id)}>
              
                <div className="fi-card__top">
                  <span className="fi-card__name">{fi.name}</span>
                  <span className="fi-card__quartier">{fi.quartier}</span>
                </div>
                <div className="fi-card__meta">
                  <span><Icon name="clock" size={13} /> {fi.schedule}</span>
                  {fi.distance != null &&
                <span className="fi-card__dist">
                      <Icon name="pin" size={13} />
                      {fi.distance < 1 ? Math.round(fi.distance * 1000) + " m" : fi.distance.toFixed(1) + " km"}
                    </span>
                }
                </div>
              </div>
            )}
          </div>

          <div className="map-wrap">
            <div id="map" ref={mapRef} />

            <div className="map-legend">
              <strong>Lecture de la carte</strong>
              <div className="map-legend__row">
                <span className="map-legend__dot map-legend__dot--fi" />
                <span>Zone d'une FI (position approximative)</span>
              </div>
              <div className="map-legend__row">
                <span className="map-legend__dot map-legend__dot--me" />
                <span>Ta position</span>
              </div>
              <div style={{ marginTop: 8, fontSize: 11, color: "var(--ink-mute)", lineHeight: 1.4 }}>
                L'adresse exacte est partagée uniquement par le référent, via WhatsApp.
              </div>
            </div>

            {selected &&
            <div className="fi-detail">
                <button className="fi-detail__close" onClick={() => setSelectedId(null)}>
                  <Icon name="close" size={14} />
                </button>
                <div className="fi-detail__quartier">{selected.city}</div>
                <div className="fi-detail__name">{selected.name}</div>
                <div className="fi-detail__row">
                  <strong>Quartier</strong>
                  <span>{selected.quartier}</span>
                </div>
                <div className="fi-detail__row">
                  <strong>Rencontres</strong>
                  <span>{selected.schedule}</span>
                </div>
                {selected.distance != null &&
              <div className="fi-detail__row">
                    <strong>Distance</strong>
                    <span>
                      {selected.distance < 1 ?
                  Math.round(selected.distance * 1000) + " m de chez toi" :
                  selected.distance.toFixed(1) + " km de chez toi"}
                    </span>
                  </div>
              }
                <a
                className="btn btn--wa fi-detail__wa"
                href={`https://wa.me/${selected.whatsapp}?text=${encodeURIComponent("Bonjour ! J'ai trouvé votre FI (" + selected.name + ") sur le site et j'aimerais vous rencontrer 🙂")}`}
                target="_blank"
                rel="noreferrer">
                
                  <img src="assets/whatsapp.png" alt="" style={{ objectFit: "cover", height: "28px", width: "48px" }} />
                  Contacter le référent
                </a>
                <div className="fi-detail__note">
                  Le référent te confirmera l'adresse exacte<br />une fois en contact.
                </div>
              </div>
            }
          </div>
        </div>
      </div>
    </div>);

};

window.FindPage = FindPage;