/* AdminPanel.jsx — reserve-team dashboard, wired to real API */

function AreaMapSection({ token, incidents, lang, selId, onSelect }) {
  const elRef = React.useRef(null);
  const mapRef = React.useRef(null);
  const incLayerRef = React.useRef(null);
  const savedLayerRef = React.useRef(null);
  const importLayerRef = React.useRef(null);
  const pendingLayerRef = React.useRef(null);
  const qgisRef = React.useRef(null);

  const [areaMode, setAreaMode] = React.useState(false);
  const [pending, setPending] = React.useState([]);
  const [saving, setSaving] = React.useState(false);
  const [qgisLoading, setQgisLoading] = React.useState(false);

  const de = lang === "de";

  React.useEffect(() => {
    const map = L.map(elRef.current, { center: window.MELD.center || [47.4985, 9.6365], zoom: 12, zoomControl: true, scrollWheelZoom: true });
    map.zoomControl.setPosition("bottomright");
    mapRef.current = map;

    const sat = L.tileLayer("https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}", {
      attribution: "© Esri, Maxar, Earthstar Geographics", maxZoom: 19
    });
    const osm = L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
      attribution: "© OpenStreetMap contributors", maxZoom: 19
    });
    sat.addTo(map);
    L.control.layers({ "Satellite": sat, "Street Map": osm }).addTo(map);

    incLayerRef.current = L.layerGroup().addTo(map);
    savedLayerRef.current = L.layerGroup().addTo(map);
    importLayerRef.current = L.layerGroup().addTo(map);
    pendingLayerRef.current = L.layerGroup().addTo(map);

    const legend = L.control({ position: "topright" });
    legend.onAdd = function() {
      const div = L.DomUtil.create("div", "area-legend");
      div.innerHTML = `<strong>Legend</strong>
        <div><span class="leg-swatch" style="background:#3388ff;opacity:.5;border:2px solid #3388ff;"></span> Imported Areas</div>
        <div><span class="leg-swatch" style="background:transparent;border:2px dashed #22aa22;"></span> Importable Areas</div>`;
      L.DomEvent.disableClickPropagation(div);
      return div;
    };
    legend.addTo(map);

    setTimeout(() => map.invalidateSize(), 120);
    doLoadSavedAreas(map);

    return () => map.remove();
  }, []);

  React.useEffect(() => {
    const layer = incLayerRef.current;
    if (!layer) return;
    layer.clearLayers();
    (incidents || []).filter(r => r.ll).forEach(r => {
      const active = r.id === selId;
      const mk = L.circleMarker(r.ll, {
        radius: active ? 13 : 10,
        fillColor: active ? "#C2613B" : "#e74c3c",
        color: "#fff", weight: active ? 3 : 2, fillOpacity: 0.95,
        zIndexOffset: active ? 1000 : 0,
      });
      if (onSelect) mk.on("click", () => onSelect(r.id));
      mk.addTo(layer);
    });
    if (selId && mapRef.current) {
      const sel = (incidents || []).find(r => r.id === selId);
      if (sel && sel.ll) mapRef.current.panTo(sel.ll, { animate: true });
    }
  }, [incidents, selId]);

  React.useEffect(() => {
    const layer = pendingLayerRef.current;
    if (!layer) return;
    layer.clearLayers();
    pending.forEach(a => {
      try {
        const gj = typeof a.geojson === "string" ? JSON.parse(a.geojson) : a.geojson;
        L.geoJSON(gj, { style: { color: "#3388ff", fillColor: "#3388ff", fillOpacity: 0.3, weight: 2 } }).addTo(layer);
      } catch (e) {}
    });
  }, [pending]);

  async function doLoadSavedAreas(mapInst) {
    try {
      const resp = await fetch("/api/admin/areas", { headers: { "Authorization": "Bearer " + token } });
      const data = await resp.json();
      if (data.success && savedLayerRef.current) {
        savedLayerRef.current.clearLayers();
        const geoLayers = [];
        data.areas.forEach(a => {
          try {
            const gj = JSON.parse(a.geojson);
            const l = L.geoJSON(gj, { style: { color: "#3388ff", fillColor: "#3388ff", fillOpacity: 0.3, weight: 2 } });
            l.addTo(savedLayerRef.current);
            geoLayers.push(l);
          } catch (e) {}
        });
        if (geoLayers.length && mapInst) {
          const grp = L.featureGroup(geoLayers.flatMap(l => l.getLayers()));
          if (grp.getLayers().length) mapInst.fitBounds(grp.getBounds(), { padding: [40, 40] });
        }
      }
    } catch (e) {}
  }

  function loadNatureReserves() {
    const map = mapRef.current;
    if (!map || !importLayerRef.current) return;
    const bounds = map.getBounds();
    const bbox = `${bounds.getSouth()},${bounds.getWest()},${bounds.getNorth()},${bounds.getEast()}`;
    const query = `[out:json][timeout:25];(way["leisure"="nature_reserve"](${bbox});way["boundary"="protected_area"](${bbox});relation["leisure"="nature_reserve"](${bbox});relation["boundary"="protected_area"](${bbox}););out geom;`;

    fetch("https://overpass-api.de/api/interpreter", { method: "POST", body: "data=" + encodeURIComponent(query) })
      .then(r => r.json())
      .then(data => {
        if (!importLayerRef.current) return;
        importLayerRef.current.clearLayers();
        data.elements.forEach(el => {
          if (el.type === "way" && el.geometry) {
            const coords = el.geometry.map(c => [c.lat, c.lon]);
            const name = (el.tags && el.tags.name) || "Nature Reserve";
            const poly = L.polygon(coords, { color: "#22aa22", fillColor: "#22aa22", fillOpacity: 0.15, weight: 2, dashArray: "5,5" });
            const div = L.DomUtil.create("div");
            div.innerHTML = `<strong>${name}</strong><br><small>${de ? "Als erlaubten Bereich importieren:" : "Import as allowed area:"}</small>`;
            const btn = L.DomUtil.create("button", "area-import-pop-btn", div);
            btn.textContent = de ? "Importieren" : "Import";
            L.DomEvent.on(btn, "click", (e) => {
              L.DomEvent.stopPropagation(e);
              const gj = { type: "Feature", geometry: { type: "Polygon", coordinates: [coords.map(c => [c[1], c[0]])] }, properties: { name } };
              setPending(prev => [...prev, { name, geojson: JSON.stringify(gj) }]);
              poly.closePopup();
            });
            poly.bindPopup(div);
            importLayerRef.current.addLayer(poly);
          }
        });
      })
      .catch(e => console.error("Overpass error", e));
  }

  async function enterAreaMode() {
    setAreaMode(true);
    try {
      const resp = await fetch("/api/admin/areas", { headers: { "Authorization": "Bearer " + token } });
      const data = await resp.json();
      if (data.success) {
        setPending(data.areas.map(a => ({ name: a.name, geojson: a.geojson })));
      }
    } catch (e) {}
    if (savedLayerRef.current) savedLayerRef.current.clearLayers();
    loadNatureReserves();
  }

  function exitAreaMode() {
    setAreaMode(false);
    setPending([]);
    if (importLayerRef.current) importLayerRef.current.clearLayers();
    doLoadSavedAreas(mapRef.current);
  }

  async function saveAreas() {
    setSaving(true);
    try {
      const resp = await fetch("/api/admin/areas", {
        method: "POST",
        headers: { "Content-Type": "application/json", "Authorization": "Bearer " + token },
        body: JSON.stringify({ areas: pending })
      });
      const data = await resp.json();
      if (data.success) exitAreaMode();
    } catch (e) {}
    setSaving(false);
  }

  async function handleQGIS(e) {
    const file = e.target.files[0];
    if (!file || !file.name.endsWith(".zip")) return;
    setQgisLoading(true);
    const fd = new FormData();
    fd.append("shapefile", file);
    try {
      const resp = await fetch("/api/admin/import-qgis", {
        method: "POST",
        headers: { "Authorization": "Bearer " + token },
        body: fd
      });
      const data = await resp.json();
      if (data.success && data.geojson) {
        const features = (data.geojson.features || []);
        features.forEach(f => {
          if (f.geometry && (f.geometry.type === "Polygon" || f.geometry.type === "MultiPolygon")) {
            const name = (f.properties && (f.properties.name || f.properties.Name || f.properties.NAME)) || "Imported";
            setPending(prev => [...prev, { name, geojson: JSON.stringify(f) }]);
          }
        });
      }
    } catch (e) {}
    setQgisLoading(false);
    if (qgisRef.current) qgisRef.current.value = "";
  }

  return (
    <div className="area-section">
      <div className="area-section-head">
        <h2 className="area-sec-title">{de ? "Vorfallkarte" : "Incident Map"}</h2>
        {!areaMode ? (
          <div style={{ display: "flex", gap: 8 }}>
            <button className="btn btn-ghost" style={{ fontSize: 13 }} onClick={() => {
              const fc = { type: "FeatureCollection", features: (incidents || []).filter(r => r.ll).map(r => ({
                type: "Feature",
                geometry: { type: "Point", coordinates: [r.ll[1], r.ll[0]] },
                properties: { id: r.id, categories: (r.cat || []).map(c => catById(c)[lang]).join(", "), description: r.description || "", status: r.status, when: r.when }
              }))};
              const a = document.createElement("a");
              a.href = URL.createObjectURL(new Blob([JSON.stringify(fc, null, 2)], { type: "application/json" }));
              a.download = "meldungen.geojson"; a.click();
            }}>
              <Ico name="map" size={15} /> GeoJSON
            </button>
            <button className="btn btn-ghost" style={{ fontSize: 13 }} onClick={enterAreaMode}>
              <Ico name="shapes" size={15} /> {de ? "Erlaubte Bereiche verwalten" : "Manage allowed areas"}
            </button>
          </div>
        ) : (
          <div style={{ display: "flex", gap: 8, flexWrap: "wrap" }}>
            <label className="btn btn-ghost" style={{ fontSize: 13, cursor: "pointer" }}>
              <Ico name="upload" size={15} /> {qgisLoading ? "…" : (de ? "Datei importieren" : "Import file")}
              <input ref={qgisRef} type="file" accept=".zip,.geojson,.json" hidden onChange={handleQGIS} disabled={qgisLoading} />
            </label>
            <button className="btn btn-ghost" style={{ fontSize: 13 }} onClick={() => setPending([])}
              title={de ? "Alle ausstehenden Bereiche löschen" : "Clear pending areas"}>
              <Ico name="trash-2" size={15} />
            </button>
            <button className="btn btn-ghost" style={{ fontSize: 13 }} onClick={exitAreaMode} disabled={saving}>
              {de ? "Abbrechen" : "Cancel"}
            </button>
            <button className="btn btn-primary" style={{ fontSize: 13 }} onClick={saveAreas} disabled={saving}>
              <Ico name="save" size={15} /> {saving ? "…" : (de ? (pending.length > 0 ? `${pending.length} speichern` : "Bereiche löschen") : (pending.length > 0 ? `Save ${pending.length}` : "Clear areas"))}
            </button>
          </div>
        )}
      </div>
      {areaMode && (
        <div className="notice notice-warn" style={{ marginBottom: 12 }}>
          <Ico name="info" size={16} />
          <span>{de ? "Klicke auf ein Schutzgebiet (grün gestrichelt) auf der Karte, um es zu importieren. Oder lade eine QGIS-Shapefile (.zip) hoch." : "Click a nature reserve (dashed green) on the map to import it. Or upload a QGIS shapefile (.zip)."}</span>
        </div>
      )}
      <div ref={elRef} className="area-map-el"></div>
      {areaMode && pending.length > 0 && (
        <div className="pending-areas">
          {pending.map((a, i) => (
            <div key={i} className="pending-area-item">
              <Ico name="map" size={14} /> <span>{a.name}</span>
              <button className="file-x" onClick={() => setPending(p => p.filter((_, j) => j !== i))}>
                <Ico name="x" size={12} />
              </button>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

function NotificationEmailsSection({ token, lang }) {
  const [emails, setEmails] = React.useState([]);
  const [newEmail, setNewEmail] = React.useState("");
  const [adding, setAdding] = React.useState(false);
  const [err, setErr] = React.useState("");
  const de = lang === "de";

  React.useEffect(() => { loadEmails(); }, []);

  async function loadEmails() {
    try {
      const resp = await fetch("/api/admin/notification-emails", { headers: { "Authorization": "Bearer " + token } });
      const data = await resp.json();
      if (data.success) setEmails(data.emails);
    } catch (e) {}
  }

  async function addEmail() {
    if (!newEmail || !newEmail.includes("@")) { setErr(de ? "Ungültige E-Mail-Adresse" : "Invalid email address"); return; }
    setAdding(true); setErr("");
    try {
      const resp = await fetch("/api/admin/notification-emails", {
        method: "POST",
        headers: { "Content-Type": "application/json", "Authorization": "Bearer " + token },
        body: JSON.stringify({ email: newEmail })
      });
      const data = await resp.json();
      if (data.success) { setNewEmail(""); loadEmails(); }
      else setErr(data.error || (de ? "Fehler" : "Error"));
    } catch (e) { setErr(de ? "Fehler" : "Error"); }
    setAdding(false);
  }

  async function toggleEmail(id, active) {
    await fetch(`/api/admin/notification-emails/${id}/toggle`, {
      method: "PUT",
      headers: { "Content-Type": "application/json", "Authorization": "Bearer " + token },
      body: JSON.stringify({ active: !active })
    });
    loadEmails();
  }

  async function deleteEmail(id) {
    await fetch(`/api/admin/notification-emails/${id}`, {
      method: "DELETE", headers: { "Authorization": "Bearer " + token }
    });
    loadEmails();
  }

  return (
    <div className="area-section">
      <div className="area-section-head">
        <h2 className="area-sec-title">{de ? "Benachrichtigungs-E-Mails" : "Notification Emails"}</h2>
      </div>
      <p style={{ fontSize: 14, color: "var(--ink-2)", margin: "0 0 16px", lineHeight: 1.5 }}>
        {de ? "Bei neuen Meldungen wird eine Benachrichtigung an diese Adressen gesendet." : "A notification is sent to these addresses when new reports arrive."}
      </p>
      <div className="notif-email-list">
        {emails.map(e => (
          <div key={e.id} className={"notif-email-row" + (e.active ? "" : " inactive")}>
            <Ico name={e.active ? "bell" : "bell-off"} size={15} style={{ color: e.active ? "var(--moss)" : "var(--ink-3)" }} />
            <span className="notif-email-addr">{e.email}</span>
            <div className="notif-email-actions">
              <button className="set-btn" title={e.active ? (de ? "Deaktivieren" : "Deactivate") : (de ? "Aktivieren" : "Activate")}
                onClick={() => toggleEmail(e.id, e.active)}>
                {e.active ? <Ico name="bell-off" size={14}/> : <Ico name="bell" size={14}/>}
              </button>
              <button className="btn-danger" style={{ padding: "6px 10px" }} onClick={() => deleteEmail(e.id)}>
                <Ico name="trash-2" size={13}/>
              </button>
            </div>
          </div>
        ))}
        {emails.length === 0 && (
          <p style={{ color: "var(--ink-3)", fontSize: 13.5, margin: 0 }}>
            {de ? "Noch keine E-Mail-Adressen konfiguriert." : "No email addresses configured yet."}
          </p>
        )}
      </div>
      <div className="notif-add">
        <input className="input" type="email" style={{ flex: 1 }}
          placeholder={de ? "Neue E-Mail-Adresse …" : "New email address …"}
          value={newEmail} onChange={e => setNewEmail(e.target.value)}
          onKeyDown={e => e.key === "Enter" && addEmail()} />
        <button className="btn btn-ghost" onClick={addEmail} disabled={adding} style={{ fontSize: 13 }}>
          <Ico name="plus" size={15}/> {de ? "Hinzufügen" : "Add"}
        </button>
      </div>
      {err && <div className="err-line" style={{ marginTop: 8 }}><Ico name="circle-alert" size={15}/> {err}</div>}
    </div>
  );
}

function transformIncident(inc) {
  let cats = [];
  if (inc.categories) {
    try { cats = JSON.parse(inc.categories); } catch (e) {}
  }
  if (!Array.isArray(cats) || cats.length === 0) cats = ["other"];

  const status = inc.status || (inc.resolved ? "resolved" : "new");

  return {
    id: "RD-" + inc.id,
    _id: inc.id,
    cat: cats,
    when: inc.incident_date_time || inc.created_at,
    status: status,
    ll: (inc.latitude != null && inc.longitude != null) ? [inc.latitude, inc.longitude] : null,
    ev: inc.file_path ? 1 : 0,
    file_path: inc.file_path,
    file_type: inc.file_type,
    anon: !inc.reporter_name,
    name: inc.reporter_name,
    email: inc.reporter_email,
    phone: inc.reporter_phone,
    description: inc.description,
  };
}

function LoginForm({ t, lang, onLogin }) {
  const [user, setUser] = React.useState("admin");
  const [pass, setPass] = React.useState("");
  const [loading, setLoading] = React.useState(false);
  const [err, setErr] = React.useState("");

  async function doLogin() {
    if (!pass) return;
    setLoading(true);
    setErr("");
    try {
      const resp = await fetch("/api/admin/login", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ username: user, password: pass }),
      });
      const data = await resp.json();
      if (data.success) {
        onLogin(data.token, data.role || user);
      } else {
        setErr(data.error || "Login failed");
        setLoading(false);
      }
    } catch (e) {
      setErr("Network error");
      setLoading(false);
    }
  }

  return (
    <div className="admin">
      <div style={{ maxWidth: 400, margin: "80px auto", textAlign: "center" }} className="anim-pop">
        <div className="success-mark" style={{ background: "var(--moss-deep)", margin: "0 auto 24px" }}>
          <Ico name="lock" size={32} />
        </div>
        <h2 className="display" style={{ fontSize: 28, color: "var(--moss-deep)", marginBottom: 6 }}>
          {t.admin_login}
        </h2>
        <p style={{ color: "var(--ink-2)", marginBottom: 28 }}>{t.admin_sub}</p>
        <div className="card" style={{ padding: 24, textAlign: "left" }}>
          <div style={{ marginBottom: 16 }}>
            <label className="field-label">{t.admin_username}</label>
            <select className="input" value={user} onChange={(e) => setUser(e.target.value)}>
              <option value="admin">admin</option>
              <option value="observer">observer</option>
            </select>
          </div>
          <div style={{ marginBottom: 20 }}>
            <label className="field-label">{t.admin_password}</label>
            <input className="input" type="password" value={pass} autoFocus
              onChange={(e) => setPass(e.target.value)}
              onKeyDown={(e) => e.key === "Enter" && doLogin()} />
          </div>
          {err && (
            <div className="err-line" style={{ marginBottom: 12 }}>
              <Ico name="circle-alert" size={15} /> {err}
            </div>
          )}
          <button className="btn btn-primary" style={{ width: "100%" }}
            onClick={doLogin} disabled={loading || !pass}>
            {loading ? <Ico name="loader" size={16} /> : <Ico name="log-in" size={16} />}
            {t.admin_login}
          </button>
        </div>
      </div>
    </div>
  );
}

function StatusBadge({ status, t }) {
  const map = { new: t.st_new, review: t.st_review, resolved: t.st_resolved };
  return <span className={"badge badge-" + status}>{map[status] || status}</span>;
}

function StatCard({ icon, label, value, sub }) {
  return (
    <div className="stat-card">
      <span className="stat-ico"><Ico name={icon} size={18} /></span>
      <div className="stat-val">{value}</div>
      <div className="stat-label">{label}</div>
      {sub && <div className="stat-sub">{sub}</div>}
    </div>
  );
}

function ExportModal({ token, lang, onClose }) {
  const de = lang === "de";
  const [from, setFrom] = React.useState("");
  const [to, setTo] = React.useState("");
  const [format, setFormat] = React.useState("csv");
  const [loading, setLoading] = React.useState(false);

  function applyPreset(preset) {
    const today = new Date();
    const pad = n => String(n).padStart(2, "0");
    const fmt = d => `${d.getFullYear()}-${pad(d.getMonth()+1)}-${pad(d.getDate())}`;
    let f, t;
    if (preset === "this-year") { f = new Date(today.getFullYear(), 0, 1); t = today; }
    else if (preset === "last-year") { f = new Date(today.getFullYear()-1, 0, 1); t = new Date(today.getFullYear()-1, 11, 31); }
    else if (preset === "last-month") { f = new Date(today.getFullYear(), today.getMonth()-1, 1); t = new Date(today.getFullYear(), today.getMonth(), 0); }
    else if (preset === "last-3-months") { f = new Date(today.getFullYear(), today.getMonth()-3, today.getDate()); t = today; }
    else if (preset === "all") { f = ""; t = ""; return setFrom(""), setTo(""); }
    setFrom(fmt(f)); setTo(fmt(t));
  }

  async function doExport() {
    setLoading(true);
    try {
      const params = new URLSearchParams({ format, lang });
      if (from) params.set("from", from);
      if (to) params.set("to", to);
      const resp = await fetch(`/api/admin/incidents/export?${params}`, {
        headers: { "Authorization": "Bearer " + token }
      });
      if (!resp.ok) throw new Error("Export failed");
      const blob = await resp.blob();
      const cd = resp.headers.get("Content-Disposition") || "";
      const match = cd.match(/filename="?([^"]+)"?/);
      const filename = match ? match[1] : `meldungen.${format}`;
      const url = URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = url; a.download = filename;
      document.body.appendChild(a); a.click(); a.remove();
      URL.revokeObjectURL(url);
      onClose();
    } catch (e) { console.error(e); }
    setLoading(false);
  }

  const presets = [
    { key: "all",          label: de ? "Alle" : "All" },
    { key: "this-year",    label: de ? "Dieses Jahr" : "This year" },
    { key: "last-3-months",label: de ? "Letzte 3 Monate" : "Last 3 months" },
    { key: "last-month",   label: de ? "Letzter Monat" : "Last month" },
    { key: "last-year",    label: de ? "Letztes Jahr" : "Last year" },
  ];

  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal-box" onClick={e => e.stopPropagation()}>
        <div className="modal-head">
          <h2 className="modal-title"><Ico name="download" size={18} /> {de ? "Meldungen exportieren" : "Export reports"}</h2>
          <button className="modal-close" onClick={onClose}><Ico name="x" size={18} /></button>
        </div>
        <div className="modal-body">
          <label className="field-label" style={{ marginBottom: 8 }}>{de ? "Zeitraum" : "Date range"}</label>
          <div className="export-presets">
            {presets.map(p => (
              <button key={p.key} className="btn btn-ghost" style={{ fontSize: 12, padding: "6px 11px" }} onClick={() => applyPreset(p.key)}>{p.label}</button>
            ))}
          </div>
          <div className="export-range">
            <div>
              <label className="field-label">{de ? "Von" : "From"}</label>
              <input className="input" type="date" value={from} onChange={e => setFrom(e.target.value)} />
            </div>
            <div>
              <label className="field-label">{de ? "Bis" : "To"}</label>
              <input className="input" type="date" value={to} onChange={e => setTo(e.target.value)} />
            </div>
          </div>
          <div style={{ marginTop: 18 }}>
            <label className="field-label" style={{ marginBottom: 8 }}>Format</label>
            <div className="seg">
              {["csv", "json", "pdf"].map(f => (
                <button key={f} className={"seg-btn" + (format === f ? " on" : "")} onClick={() => setFormat(f)}>
                  {f.toUpperCase()}
                </button>
              ))}
            </div>
          </div>
          <button className="btn btn-primary" style={{ marginTop: 22, width: "100%" }} onClick={doExport} disabled={loading}>
            <Ico name="download" size={15} /> {loading ? "…" : (de ? "Herunterladen" : "Download")}
          </button>
        </div>
      </div>
    </div>
  );
}

function NotifModal({ token, lang, onClose }) {
  const de = lang === "de";
  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal-box" onClick={e => e.stopPropagation()}>
        <div className="modal-head">
          <h2 className="modal-title"><Ico name="bell" size={18} /> {de ? "Benachrichtigungs-E-Mails" : "Notification Emails"}</h2>
          <button className="modal-close" onClick={onClose}><Ico name="x" size={18} /></button>
        </div>
        <div className="modal-body">
          <NotificationEmailsSection token={token} lang={lang} />
        </div>
      </div>
    </div>
  );
}

function AdminPanel({ lang, t }) {
  const [token, setToken] = React.useState(() => sessionStorage.getItem("meld_admin_token") || "");
  const [role, setRole] = React.useState(() => sessionStorage.getItem("meld_admin_role") || "");
  const [incidents, setIncidents] = React.useState([]);
  const [loading, setLoading] = React.useState(false);
  const [sel, setSel] = React.useState(null);
  const [overrides, setOverrides] = React.useState({});
  const [statusFilter, setStatusFilter] = React.useState("all");
  const [catFilter, setCatFilter] = React.useState("all");
  const [q, setQ] = React.useState("");
  const [notifOpen, setNotifOpen] = React.useState(false);
  const [exportOpen, setExportOpen] = React.useState(false);
  const de = lang === "de";

  const withStatus = (r) => overrides[r.id] !== undefined ? overrides[r.id] : r.status;

  function logout() {
    sessionStorage.removeItem("meld_admin_token");
    sessionStorage.removeItem("meld_admin_role");
    setToken(""); setRole(""); setIncidents([]); setSel(null); setOverrides({});
  }

  async function fetchIncidents(tok) {
    setLoading(true);
    try {
      const resp = await fetch("/api/admin/incidents", {
        headers: { "Authorization": "Bearer " + tok },
      });
      const data = await resp.json();
      if (data.success) {
        const transformed = data.incidents.map(transformIncident);
        setIncidents(transformed);
        if (transformed.length > 0 && !sel) setSel(transformed[0].id);
      } else {
        logout();
      }
    } catch (e) {
      console.error("Failed to fetch incidents", e);
    } finally {
      setLoading(false);
    }
  }

  React.useEffect(() => {
    if (token) fetchIncidents(token);
  }, [token]);

  async function updateStatus(reportId, newStatus) {
    setOverrides((o) => ({ ...o, [reportId]: newStatus }));
    const report = incidents.find((r) => r.id === reportId);
    if (!report) return;
    try {
      await fetch(`/api/admin/incidents/${report._id}/status`, {
        method: "PUT",
        headers: { "Content-Type": "application/json", "Authorization": "Bearer " + token },
        body: JSON.stringify({ status: newStatus }),
      });
    } catch (e) {
      setOverrides((o) => { const n = { ...o }; delete n[reportId]; return n; });
    }
  }

  async function deleteIncident(reportId) {
    const report = incidents.find((r) => r.id === reportId);
    if (!report) return;
    if (!confirm(t.delete_confirm)) return;
    try {
      await fetch(`/api/admin/incidents/${report._id}`, {
        method: "DELETE",
        headers: { "Authorization": "Bearer " + token },
      });
      setIncidents((prev) => prev.filter((r) => r.id !== reportId));
      if (sel === reportId) {
        const remaining = incidents.filter((r) => r.id !== reportId);
        setSel(remaining.length > 0 ? remaining[0].id : null);
      }
    } catch (e) {
      console.error("Delete failed", e);
    }
  }

  if (!token) {
    return (
      <LoginForm t={t} lang={lang} onLogin={(tok, r) => {
        sessionStorage.setItem("meld_admin_token", tok);
        sessionStorage.setItem("meld_admin_role", r || "admin");
        setToken(tok);
        setRole(r || "admin");
      }} />
    );
  }

  const filtered = incidents.filter((r) => {
    if (statusFilter !== "all" && withStatus(r) !== statusFilter) return false;
    if (catFilter !== "all" && !r.cat.includes(catFilter)) return false;
    if (q) {
      const hay = ([r.description, r.id, r.cat.map((c) => catById(c)[lang]).join(" ")]).join(" ").toLowerCase();
      if (!hay.includes(q.toLowerCase())) return false;
    }
    return true;
  });

  const counts = {
    total: incidents.length,
    new: incidents.filter((r) => withStatus(r) === "new").length,
  };
  const tally = {};
  incidents.forEach((r) => r.cat.forEach((c) => (tally[c] = (tally[c] || 0) + 1)));
  const topCat = Object.entries(tally).sort((a, b) => b[1] - a[1])[0];

  const selReport = incidents.find((r) => r.id === sel);

  return (
    <div className="admin">
      {notifOpen && <NotifModal token={token} lang={lang} onClose={() => setNotifOpen(false)} />}
      {exportOpen && <ExportModal token={token} lang={lang} onClose={() => setExportOpen(false)} />}
      <div className="admin-head">
        <div>
          <div className="eyebrow">{t.admin_sub}</div>
          <h1 className="display admin-h1">{t.admin_title}</h1>
        </div>
        <div style={{ display: "flex", gap: 8, alignItems: "center" }}>
          <button className="btn btn-ghost" style={{ fontSize: 13 }} onClick={() => setNotifOpen(true)}>
            <Ico name="bell" size={15} /> {de ? "Benachrichtigungen" : "Notifications"}
          </button>
          <button className="btn btn-ghost" onClick={logout} style={{ fontSize: 13 }}>
            <Ico name="log-out" size={15} /> {t.admin_logout}
          </button>
        </div>
      </div>

      {loading ? (
        <div className="admin-loading">
          <Ico name="loader" size={20} /> {t.loading}
        </div>
      ) : (
        <>
          <div className="stat-row">
            <StatCard icon="layers" label={t.a_total} value={counts.total} />
            <StatCard icon="bell-dot" label={t.a_new} value={counts.new} />
            <StatCard icon="calendar-days" label={t.a_week} value={incidents.length} />
            <StatCard
              icon={topCat ? catById(topCat[0]).icon : "circle-help"}
              label={t.a_hot}
              value={topCat ? catById(topCat[0])[lang] : "—"}
              sub={topCat ? topCat[1] + " ×" : null}
            />
          </div>

          <div className="admin-toolbar">
            <div className="search-box">
              <Ico name="search" size={16} />
              <input className="search-in" placeholder={t.f_search} value={q}
                onChange={(e) => setQ(e.target.value)} />
            </div>
            <div className="filter-segs">
              {["all", "new", "review", "resolved"].map((s) => (
                <button key={s} className={"fseg" + (statusFilter === s ? " on" : "")}
                  onClick={() => setStatusFilter(s)}>
                  {s === "all" ? t.a_filter_all : { new: t.st_new, review: t.st_review, resolved: t.st_resolved }[s]}
                </button>
              ))}
            </div>
            <select className="input cat-select" value={catFilter}
              onChange={(e) => setCatFilter(e.target.value)}>
              <option value="all">{t.f_category}: {t.a_filter_all}</option>
              {window.MELD.categories.map((c) => (
                <option key={c.id} value={c.id}>{c[lang]}</option>
              ))}
            </select>
            <div className="export-btns">
              <button className="btn btn-ghost" style={{ fontSize: 13 }} onClick={() => setExportOpen(true)}>
                <Ico name="download" size={15} /> {de ? "Exportieren" : "Export"}
              </button>
            </div>
          </div>

          <div className="admin-workspace">
            <div className="admin-map-col">
              <AreaMapSection token={token} incidents={incidents} lang={lang} t={t} selId={sel} onSelect={setSel} />
            </div>

            <div className="admin-right-col">
              <div className="admin-list">
                <div className="list-count">{filtered.length} {t.of_reports}</div>
                {filtered.map((r) => (
                  <button key={r.id} className={"rep-row" + (r.id === sel ? " sel" : "")}
                    onClick={() => setSel(r.id)}>
                    <div className="rep-icos">
                      {r.cat.slice(0, 2).map((c) => (
                        <span key={c} className="rep-ico"><Ico name={catById(c).icon} size={16} /></span>
                      ))}
                    </div>
                    <div className="rep-main">
                      <div className="rep-top">
                        <span className="rep-cat">
                          {r.cat.length ? r.cat.map((c) => catById(c)[lang]).join(" · ") : t.no_categories}
                        </span>
                        <StatusBadge status={withStatus(r)} t={t} />
                      </div>
                      <div className="rep-meta">
                        {r.ll && <span><Ico name="map-pin" size={12} /> {r.ll[0].toFixed(4)}, {r.ll[1].toFixed(4)}</span>}
                        <span><Ico name="clock" size={12} /> {fmtWhen(r.when, lang)}</span>
                        {r.ev > 0 && <span><Ico name="paperclip" size={12} /> {r.ev}</span>}
                      </div>
                    </div>
                  </button>
                ))}
                {filtered.length === 0 && (
                  <div style={{ padding: "30px 16px", color: "var(--ink-3)", fontSize: 14, textAlign: "center" }}>
                    {incidents.length === 0 ? "—" : lang === "de" ? "Keine Meldungen gefunden." : "No reports found."}
                  </div>
                )}
              </div>

              <div className="admin-detail-slot">
              {selReport ? (
                <div className="detail-card anim-up" key={selReport.id}>
                  <div className="detail-card-head">
                    <div>
                      <span className="detail-id">{selReport.id}</span>
                      <div className="detail-cats">
                        {selReport.cat.map((c) => (
                          <span key={c} className="dcat">
                            <Ico name={catById(c).icon} size={14} /> {catById(c)[lang]}
                          </span>
                        ))}
                      </div>
                    </div>
                    <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
                      <StatusBadge status={withStatus(selReport)} t={t} />
                      <button className="modal-close" onClick={() => setSel(null)}><Ico name="x" size={16} /></button>
                    </div>
                  </div>

                  <div className="detail-meta">
                    {selReport.ll && (
                      <span><Ico name="map-pin" size={14} /> {selReport.ll[0].toFixed(5)}, {selReport.ll[1].toFixed(5)}</span>
                    )}
                    <span><Ico name="clock" size={14} /> {fmtWhen(selReport.when, lang)}</span>
                    <span>
                      <Ico name="user" size={14} />
                      {selReport.anon ? t.detail_anon : selReport.name || t.detail_anon}
                    </span>
                    {selReport.email && <span><Ico name="mail" size={14} /> {selReport.email}</span>}
                    {selReport.phone && <span><Ico name="phone" size={14} /> {selReport.phone}</span>}
                  </div>

                  <div className="detail-block">
                    <div className="detail-k">{t.detail_desc}</div>
                    <p className="detail-desc">{selReport.description || "—"}</p>
                  </div>

                  <div className="detail-block">
                    <div className="detail-k">{t.detail_evidence}</div>
                    {selReport.ev > 0 ? (
                      <div className="ev-thumbs">
                        {selReport.file_type && selReport.file_type.startsWith("image") ? (
                          <a href={"/uploads/" + selReport.file_path} target="_blank" rel="noopener">
                            <img className="ev-thumb-img" src={"/uploads/" + selReport.file_path} alt="" />
                          </a>
                        ) : (
                          <a href={"/uploads/" + selReport.file_path} target="_blank" rel="noopener">
                            <div className="ev-thumb"><Ico name="video" size={18} /></div>
                          </a>
                        )}
                      </div>
                    ) : <p className="detail-desc muted">—</p>}
                  </div>

                  <div className="detail-block">
                    <div className="detail-k">{t.detail_setstatus}</div>
                    <div className="status-set">
                      {["new", "review", "resolved"].map((s) => (
                        <button key={s}
                          className={"set-btn set-" + s + (withStatus(selReport) === s ? " on" : "")}
                          onClick={() => updateStatus(selReport.id, s)}>
                          {{ new: t.st_new, review: t.st_review, resolved: t.st_resolved }[s]}
                        </button>
                      ))}
                    </div>
                  </div>

                  <div className="detail-actions">
                    <button className="btn-danger" onClick={() => deleteIncident(selReport.id)}>
                      <Ico name="trash-2" size={14} /> {t.delete_btn}
                    </button>
                  </div>
                </div>
              ) : (
                <div className="detail-empty">{t.detail_none}</div>
              )}
              </div>
            </div>
          </div>
        </>
      )}
    </div>
  );
}

window.AdminPanel = AdminPanel;
