/* global React, Icon */
// ============================================================================
// DÉFINITIONS DE BASE · Référentiel géographique
// ----------------------------------------------------------------------------
// Module d'administration des subdivisions administratives utilisées par
// la plateforme. Hiérarchie :
//   Pays (countries) → Région → Département → Arrondissement → Commune → Quartier
//
// Au seed initial, le Sénégal est entièrement peuplé (14 régions, 46
// départements, 168 arrondissements, 536 communes). Les autres pays sont
// dans le catalogue ISO 3166-1 ; chaque org peut compléter sa propre
// liste de quartiers (RLS admin).
//
// Écran à 6 onglets, chacun = un niveau. Filtrage en cascade par le
// parent + recherche texte + CRUD inline.
// ============================================================================

const { useState: useStatePL, useMemo: useMemoPL, useEffect: useEffectPL } = React;

function ProjectPlanning({ t, lang, isSuperAdmin }) {
  const [tab, setTab] = useStatePL("countries");

  // ──────────────────────────────────────────────────────────────────────
  return (
    <div className="screen" data-screen-label="Definitions de base">
      <div className="row" style={{ alignItems: "center", marginBottom: 12 }}>
        <div>
          <div className="screen-title">{lang === "fr" ? "Définitions de base" : "Base definitions"}</div>
          <div className="text-faint" style={{ fontSize: 12, marginTop: 2 }}>
            {lang === "fr"
              ? "Référentiel géographique partagé : pays, régions, départements, arrondissements, communes, quartiers."
              : "Shared geographic catalog: countries, regions, departments, arrondissements, communes, neighborhoods."}
          </div>
        </div>
      </div>

      {/* Onglets · 6 niveaux */}
      <div className="seg" style={{ marginBottom: 16 }}>
        <button className={"seg-btn" + (tab === "countries"        ? " active" : "")} onClick={() => setTab("countries")}>
          <Icon.globe /> {lang === "fr" ? "Pays" : "Countries"}
        </button>
        <button className={"seg-btn" + (tab === "regions"          ? " active" : "")} onClick={() => setTab("regions")}>
          {lang === "fr" ? "Régions" : "Regions"}
        </button>
        <button className={"seg-btn" + (tab === "departments"      ? " active" : "")} onClick={() => setTab("departments")}>
          {lang === "fr" ? "Départements" : "Departments"}
        </button>
        <button className={"seg-btn" + (tab === "arrondissements"  ? " active" : "")} onClick={() => setTab("arrondissements")}>
          {lang === "fr" ? "Arrondissements" : "Arrondissements"}
        </button>
        <button className={"seg-btn" + (tab === "communes"         ? " active" : "")} onClick={() => setTab("communes")}>
          {lang === "fr" ? "Communes" : "Communes"}
        </button>
        <button className={"seg-btn" + (tab === "quartiers"        ? " active" : "")} onClick={() => setTab("quartiers")}>
          {lang === "fr" ? "Quartiers" : "Neighborhoods"}
        </button>
      </div>

      {tab === "countries"       && <CountriesTab       lang={lang} isSuperAdmin={isSuperAdmin} />}
      {tab === "regions"         && <RegionsTab         lang={lang} isSuperAdmin={isSuperAdmin} />}
      {tab === "departments"     && <DepartmentsTab     lang={lang} isSuperAdmin={isSuperAdmin} />}
      {tab === "arrondissements" && <ArrondissementsTab lang={lang} isSuperAdmin={isSuperAdmin} />}
      {tab === "communes"        && <CommunesTab        lang={lang} isSuperAdmin={isSuperAdmin} />}
      {tab === "quartiers"       && <QuartiersTab       lang={lang} isSuperAdmin={isSuperAdmin} />}
    </div>
  );
}

// ── Helpers communs ─────────────────────────────────────────────────────
function _searchMatch(needle, ...haystacks) {
  if (!needle) return true;
  const n = needle.toLowerCase();
  return haystacks.some((h) => h && String(h).toLowerCase().includes(n));
}

const _inp = {
  padding: "7px 9px", borderRadius: 6, border: "1px solid var(--line)",
  fontSize: 12.5, background: "var(--bg, white)", color: "var(--text)",
};
const _btnRow = { display: "flex", gap: 6, marginLeft: "auto" };

function _toolbar({ search, setSearch, count, addLabel, onAdd, canAdd, extras }) {
  return (
    <div className="card-head" style={{ flexWrap: "wrap", gap: 10 }}>
      <input style={{ ..._inp, minWidth: 260, flex: 1 }} placeholder="🔎 Filtrer…"
        value={search} onChange={(e) => setSearch(e.target.value)} />
      <span className="text-faint" style={{ fontSize: 12 }}>{count} résultats</span>
      {extras}
      {canAdd && (
        <button className="btn xs primary" onClick={onAdd} style={{ marginLeft: "auto" }}>
          <Icon.plus /> {addLabel}
        </button>
      )}
    </div>
  );
}

// ============================================================================
// Onglet · Pays
// ============================================================================
function CountriesTab({ lang, isSuperAdmin }) {
  const { data, loading, refresh } = window.melr.useCountries();
  const [search, setSearch] = useStatePL("");
  const [editing, setEditing] = useStatePL(null);
  const [creating, setCreating] = useStatePL(false);

  const rows = useMemoPL(() => {
    return (data || []).filter((r) => _searchMatch(search, r.iso2, r.name_fr, r.name_en, r.region));
  }, [data, search]);

  return (
    <div className="card">
      {_toolbar({
        search, setSearch, count: rows.length,
        addLabel: lang === "fr" ? "Nouveau pays" : "New country",
        onAdd: () => setCreating(true),
        canAdd: isSuperAdmin,
      })}
      <div className="card-body flush" style={{ maxHeight: "70vh", overflow: "auto" }}>
        {loading
          ? <div className="text-faint" style={{ padding: 22, textAlign: "center" }}>{lang === "fr" ? "Chargement…" : "Loading…"}</div>
          : (
            <table className="tbl">
              <thead><tr>
                <th>ISO2</th>
                <th>{lang === "fr" ? "Nom (fr)" : "Name (fr)"}</th>
                <th>{lang === "fr" ? "Nom (en)" : "Name (en)"}</th>
                <th>{lang === "fr" ? "Région ONU" : "UN region"}</th>
                {isSuperAdmin && <th style={{ width: 60 }}></th>}
              </tr></thead>
              <tbody>
                {rows.map((r) => (
                  <tr key={r.iso2}>
                    <td className="mono strong">{r.iso2}</td>
                    <td>{r.name_fr}</td>
                    <td className="muted">{r.name_en}</td>
                    <td className="muted">{r.region || "—"}</td>
                    {isSuperAdmin && (
                      <td className="num">
                        <button className="iconbtn" title={lang === "fr" ? "Modifier" : "Edit"} onClick={() => setEditing(r)}>
                          <Icon.edit />
                        </button>
                      </td>
                    )}
                  </tr>
                ))}
              </tbody>
            </table>
          )}
      </div>
      {(creating || editing) && <CountryModal lang={lang} row={editing} onClose={() => { setEditing(null); setCreating(false); }} onSaved={async () => { setEditing(null); setCreating(false); await refresh(); }} />}
    </div>
  );
}

// ============================================================================
// Onglet · Régions
// ============================================================================
function RegionsTab({ lang, isSuperAdmin }) {
  const [country, setCountry] = useStatePL("SN");
  const { data: countries } = window.melr.useCountries();
  const { data, loading, refresh } = window.melr.useGeoRegions(country);
  const [search, setSearch] = useStatePL("");
  const [editing, setEditing] = useStatePL(null);
  const [creating, setCreating] = useStatePL(false);

  const rows = useMemoPL(() => {
    return (data || []).filter((r) => _searchMatch(search, r.code, r.name_fr, r.name_en));
  }, [data, search]);

  return (
    <div className="card">
      <div className="card-head" style={{ flexWrap: "wrap", gap: 10 }}>
        <label style={{ display: "flex", alignItems: "center", gap: 6 }}>
          <span style={{ fontSize: 11, color: "var(--text-faint)", textTransform: "uppercase" }}>{lang === "fr" ? "Pays" : "Country"} :</span>
          <select style={_inp} value={country || ""} onChange={(e) => setCountry(e.target.value || null)}>
            <option value="">— Tous —</option>
            {(countries || []).map((c) => <option key={c.iso2} value={c.iso2}>{c.name_fr}</option>)}
          </select>
        </label>
        <input style={{ ..._inp, minWidth: 240, flex: 1 }} placeholder="🔎 Filtrer…" value={search} onChange={(e) => setSearch(e.target.value)} />
        <span className="text-faint" style={{ fontSize: 12 }}>{rows.length} résultats</span>
        {isSuperAdmin && (
          <button className="btn xs primary" onClick={() => setCreating(true)} disabled={!country}>
            <Icon.plus /> {lang === "fr" ? "Nouvelle région" : "New region"}
          </button>
        )}
      </div>
      <div className="card-body flush" style={{ maxHeight: "70vh", overflow: "auto" }}>
        {!country ? (
          <div className="text-faint" style={{ padding: 22, textAlign: "center" }}>
            {lang === "fr" ? "Choisir un pays pour afficher ses régions." : "Pick a country to list its regions."}
          </div>
        ) : loading ? (
          <div className="text-faint" style={{ padding: 22, textAlign: "center" }}>{lang === "fr" ? "Chargement…" : "Loading…"}</div>
        ) : (
          <table className="tbl">
            <thead><tr>
              <th>{lang === "fr" ? "Code" : "Code"}</th>
              <th>{lang === "fr" ? "Nom (fr)" : "Name (fr)"}</th>
              <th>{lang === "fr" ? "Nom (en)" : "Name (en)"}</th>
              {isSuperAdmin && <th style={{ width: 60 }}></th>}
            </tr></thead>
            <tbody>
              {rows.map((r) => (
                <tr key={r.id}>
                  <td className="mono">{r.code || "—"}</td>
                  <td className="strong">{r.name_fr}</td>
                  <td className="muted">{r.name_en || "—"}</td>
                  {isSuperAdmin && (
                    <td className="num">
                      <button className="iconbtn" onClick={() => setEditing(r)}><Icon.edit /></button>
                    </td>
                  )}
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </div>
      {(creating || editing) && <RegionModal lang={lang} row={editing} country={country} onClose={() => { setEditing(null); setCreating(false); }} onSaved={async () => { setEditing(null); setCreating(false); await refresh(); }} />}
    </div>
  );
}

// ============================================================================
// Onglet · Départements (filtre par région)
// ============================================================================
function DepartmentsTab({ lang, isSuperAdmin }) {
  const [country, setCountry] = useStatePL("SN");
  const [regionId, setRegionId] = useStatePL(null);
  const { data: countries } = window.melr.useCountries();
  const { data: regions } = window.melr.useGeoRegions(country);
  const { data, loading, refresh } = window.melr.useGeoDepartments(regionId);
  const [search, setSearch] = useStatePL("");
  const [editing, setEditing] = useStatePL(null);
  const [creating, setCreating] = useStatePL(false);

  const rows = useMemoPL(() => (data || []).filter((r) => _searchMatch(search, r.code, r.name_fr, r.name_en)), [data, search]);

  return (
    <div className="card">
      <div className="card-head" style={{ flexWrap: "wrap", gap: 10 }}>
        <label style={{ display: "flex", alignItems: "center", gap: 6 }}>
          <span style={{ fontSize: 11, color: "var(--text-faint)" }}>{lang === "fr" ? "Pays" : "Country"} :</span>
          <select style={_inp} value={country || ""} onChange={(e) => { setCountry(e.target.value || null); setRegionId(null); }}>
            {(countries || []).map((c) => <option key={c.iso2} value={c.iso2}>{c.name_fr}</option>)}
          </select>
        </label>
        <label style={{ display: "flex", alignItems: "center", gap: 6 }}>
          <span style={{ fontSize: 11, color: "var(--text-faint)" }}>{lang === "fr" ? "Région" : "Region"} :</span>
          <select style={_inp} value={regionId || ""} onChange={(e) => setRegionId(e.target.value || null)}>
            <option value="">— {lang === "fr" ? "Choisir" : "Pick"} —</option>
            {(regions || []).map((r) => <option key={r.id} value={r.id}>{r.name_fr}</option>)}
          </select>
        </label>
        <input style={{ ..._inp, minWidth: 200, flex: 1 }} placeholder="🔎 Filtrer…" value={search} onChange={(e) => setSearch(e.target.value)} />
        <span className="text-faint" style={{ fontSize: 12 }}>{rows.length} résultats</span>
        {isSuperAdmin && regionId && (
          <button className="btn xs primary" onClick={() => setCreating(true)}>
            <Icon.plus /> {lang === "fr" ? "Nouveau département" : "New department"}
          </button>
        )}
      </div>
      <div className="card-body flush" style={{ maxHeight: "70vh", overflow: "auto" }}>
        {!regionId ? (
          <div className="text-faint" style={{ padding: 22, textAlign: "center" }}>{lang === "fr" ? "Choisir une région." : "Pick a region."}</div>
        ) : loading ? (
          <div className="text-faint" style={{ padding: 22, textAlign: "center" }}>{lang === "fr" ? "Chargement…" : "Loading…"}</div>
        ) : (
          <table className="tbl">
            <thead><tr>
              <th>{lang === "fr" ? "Code" : "Code"}</th>
              <th>{lang === "fr" ? "Nom (fr)" : "Name (fr)"}</th>
              <th>{lang === "fr" ? "Nom (en)" : "Name (en)"}</th>
              {isSuperAdmin && <th style={{ width: 60 }}></th>}
            </tr></thead>
            <tbody>
              {rows.map((r) => (
                <tr key={r.id}>
                  <td className="mono">{r.code || "—"}</td>
                  <td className="strong">{r.name_fr}</td>
                  <td className="muted">{r.name_en || "—"}</td>
                  {isSuperAdmin && <td className="num"><button className="iconbtn" onClick={() => setEditing(r)}><Icon.edit /></button></td>}
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </div>
      {(creating || editing) && <DepartmentModal lang={lang} row={editing} regionId={regionId} onClose={() => { setEditing(null); setCreating(false); }} onSaved={async () => { setEditing(null); setCreating(false); await refresh(); }} />}
    </div>
  );
}

// ============================================================================
// Onglet · Arrondissements (filtre par département)
// ============================================================================
function ArrondissementsTab({ lang, isSuperAdmin }) {
  const [country, setCountry] = useStatePL("SN");
  const [regionId, setRegionId] = useStatePL(null);
  const [deptId, setDeptId] = useStatePL(null);
  const { data: countries } = window.melr.useCountries();
  const { data: regions } = window.melr.useGeoRegions(country);
  const { data: departments } = window.melr.useGeoDepartments(regionId);
  const { data, loading, refresh } = window.melr.useGeoArrondissements(deptId);
  const [search, setSearch] = useStatePL("");
  const [editing, setEditing] = useStatePL(null);
  const [creating, setCreating] = useStatePL(false);

  const rows = useMemoPL(() => (data || []).filter((r) => _searchMatch(search, r.name_fr, r.name_en)), [data, search]);

  return (
    <div className="card">
      <div className="card-head" style={{ flexWrap: "wrap", gap: 10 }}>
        <select style={_inp} value={country || ""} onChange={(e) => { setCountry(e.target.value || null); setRegionId(null); setDeptId(null); }}>
          {(countries || []).map((c) => <option key={c.iso2} value={c.iso2}>{c.name_fr}</option>)}
        </select>
        <select style={_inp} value={regionId || ""} onChange={(e) => { setRegionId(e.target.value || null); setDeptId(null); }}>
          <option value="">— {lang === "fr" ? "Région" : "Region"} —</option>
          {(regions || []).map((r) => <option key={r.id} value={r.id}>{r.name_fr}</option>)}
        </select>
        <select style={_inp} value={deptId || ""} onChange={(e) => setDeptId(e.target.value || null)} disabled={!regionId}>
          <option value="">— {lang === "fr" ? "Département" : "Department"} —</option>
          {(departments || []).map((d) => <option key={d.id} value={d.id}>{d.name_fr}</option>)}
        </select>
        <input style={{ ..._inp, minWidth: 180, flex: 1 }} placeholder="🔎 Filtrer…" value={search} onChange={(e) => setSearch(e.target.value)} />
        <span className="text-faint" style={{ fontSize: 12 }}>{rows.length} résultats</span>
        {isSuperAdmin && deptId && (
          <button className="btn xs primary" onClick={() => setCreating(true)}>
            <Icon.plus /> {lang === "fr" ? "Nouvel arr." : "New arr."}
          </button>
        )}
      </div>
      <div className="card-body flush" style={{ maxHeight: "70vh", overflow: "auto" }}>
        {!deptId ? (
          <div className="text-faint" style={{ padding: 22, textAlign: "center" }}>{lang === "fr" ? "Choisir un département." : "Pick a department."}</div>
        ) : loading ? (
          <div className="text-faint" style={{ padding: 22, textAlign: "center" }}>{lang === "fr" ? "Chargement…" : "Loading…"}</div>
        ) : (
          <table className="tbl">
            <thead><tr>
              <th>{lang === "fr" ? "Nom (fr)" : "Name (fr)"}</th>
              <th>{lang === "fr" ? "Nom (en)" : "Name (en)"}</th>
              {isSuperAdmin && <th style={{ width: 60 }}></th>}
            </tr></thead>
            <tbody>
              {rows.map((r) => (
                <tr key={r.id}>
                  <td className="strong">{r.name_fr}</td>
                  <td className="muted">{r.name_en || "—"}</td>
                  {isSuperAdmin && <td className="num"><button className="iconbtn" onClick={() => setEditing(r)}><Icon.edit /></button></td>}
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </div>
      {(creating || editing) && <ArrondissementModal lang={lang} row={editing} deptId={deptId} onClose={() => { setEditing(null); setCreating(false); }} onSaved={async () => { setEditing(null); setCreating(false); await refresh(); }} />}
    </div>
  );
}

// ============================================================================
// Onglet · Communes (filtre par arrondissement)
// ============================================================================
function CommunesTab({ lang, isSuperAdmin }) {
  const [country, setCountry] = useStatePL("SN");
  const [regionId, setRegionId] = useStatePL(null);
  const [deptId, setDeptId] = useStatePL(null);
  const [arrId, setArrId] = useStatePL(null);
  const { data: countries } = window.melr.useCountries();
  const { data: regions } = window.melr.useGeoRegions(country);
  const { data: departments } = window.melr.useGeoDepartments(regionId);
  const { data: arrondissements } = window.melr.useGeoArrondissements(deptId);
  const { data, loading, refresh } = window.melr.useGeoCommunes(arrId);
  const [search, setSearch] = useStatePL("");
  const [editing, setEditing] = useStatePL(null);
  const [creating, setCreating] = useStatePL(false);

  const rows = useMemoPL(() => (data || []).filter((r) => _searchMatch(search, r.name_fr, r.name_en, r.type, r.ville_parent)), [data, search]);

  return (
    <div className="card">
      <div className="card-head" style={{ flexWrap: "wrap", gap: 8 }}>
        <select style={_inp} value={country || ""} onChange={(e) => { setCountry(e.target.value || null); setRegionId(null); setDeptId(null); setArrId(null); }}>
          {(countries || []).map((c) => <option key={c.iso2} value={c.iso2}>{c.name_fr}</option>)}
        </select>
        <select style={_inp} value={regionId || ""} onChange={(e) => { setRegionId(e.target.value || null); setDeptId(null); setArrId(null); }}>
          <option value="">— Région —</option>
          {(regions || []).map((r) => <option key={r.id} value={r.id}>{r.name_fr}</option>)}
        </select>
        <select style={_inp} value={deptId || ""} onChange={(e) => { setDeptId(e.target.value || null); setArrId(null); }} disabled={!regionId}>
          <option value="">— Département —</option>
          {(departments || []).map((d) => <option key={d.id} value={d.id}>{d.name_fr}</option>)}
        </select>
        <select style={_inp} value={arrId || ""} onChange={(e) => setArrId(e.target.value || null)} disabled={!deptId}>
          <option value="">— Arrondissement —</option>
          {(arrondissements || []).map((a) => <option key={a.id} value={a.id}>{a.name_fr}</option>)}
        </select>
        <input style={{ ..._inp, minWidth: 160, flex: 1 }} placeholder="🔎 Filtrer…" value={search} onChange={(e) => setSearch(e.target.value)} />
        <span className="text-faint" style={{ fontSize: 12 }}>{rows.length} résultats</span>
        {isSuperAdmin && arrId && (
          <button className="btn xs primary" onClick={() => setCreating(true)}>
            <Icon.plus /> {lang === "fr" ? "Nouvelle commune" : "New commune"}
          </button>
        )}
      </div>
      <div className="card-body flush" style={{ maxHeight: "70vh", overflow: "auto" }}>
        {!arrId ? (
          <div className="text-faint" style={{ padding: 22, textAlign: "center" }}>{lang === "fr" ? "Choisir un arrondissement." : "Pick an arrondissement."}</div>
        ) : loading ? (
          <div className="text-faint" style={{ padding: 22, textAlign: "center" }}>{lang === "fr" ? "Chargement…" : "Loading…"}</div>
        ) : (
          <table className="tbl">
            <thead><tr>
              <th>{lang === "fr" ? "Nom" : "Name"}</th>
              <th>{lang === "fr" ? "Type" : "Type"}</th>
              <th>{lang === "fr" ? "Ville parent" : "Parent city"}</th>
              {isSuperAdmin && <th style={{ width: 60 }}></th>}
            </tr></thead>
            <tbody>
              {rows.map((r) => (
                <tr key={r.id}>
                  <td className="strong">{r.name_fr}</td>
                  <td className="muted">{r.type || "—"}</td>
                  <td className="muted">{r.ville_parent || "—"}</td>
                  {isSuperAdmin && <td className="num"><button className="iconbtn" onClick={() => setEditing(r)}><Icon.edit /></button></td>}
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </div>
      {(creating || editing) && <CommuneModal lang={lang} row={editing} arrId={arrId} onClose={() => { setEditing(null); setCreating(false); }} onSaved={async () => { setEditing(null); setCreating(false); await refresh(); }} />}
    </div>
  );
}

// ============================================================================
// Onglet · Quartiers (filtre par commune)
// ============================================================================
function QuartiersTab({ lang, isSuperAdmin }) {
  const [country, setCountry] = useStatePL("SN");
  const [regionId, setRegionId] = useStatePL(null);
  const [deptId, setDeptId] = useStatePL(null);
  const [arrId, setArrId] = useStatePL(null);
  const [commId, setCommId] = useStatePL(null);
  const { data: countries } = window.melr.useCountries();
  const { data: regions } = window.melr.useGeoRegions(country);
  const { data: departments } = window.melr.useGeoDepartments(regionId);
  const { data: arrondissements } = window.melr.useGeoArrondissements(deptId);
  const { data: communes } = window.melr.useGeoCommunes(arrId);
  const { data, loading, refresh } = window.melr.useGeoQuartiers(commId);
  const [search, setSearch] = useStatePL("");
  const [editing, setEditing] = useStatePL(null);
  const [creating, setCreating] = useStatePL(false);

  const rows = useMemoPL(() => (data || []).filter((r) => _searchMatch(search, r.name_fr, r.name_en)), [data, search]);

  return (
    <div className="card">
      <div className="card-head" style={{ flexWrap: "wrap", gap: 8 }}>
        <select style={_inp} value={country || ""} onChange={(e) => { setCountry(e.target.value || null); setRegionId(null); setDeptId(null); setArrId(null); setCommId(null); }}>
          {(countries || []).map((c) => <option key={c.iso2} value={c.iso2}>{c.name_fr}</option>)}
        </select>
        <select style={_inp} value={regionId || ""} onChange={(e) => { setRegionId(e.target.value || null); setDeptId(null); setArrId(null); setCommId(null); }}>
          <option value="">— Région —</option>
          {(regions || []).map((r) => <option key={r.id} value={r.id}>{r.name_fr}</option>)}
        </select>
        <select style={_inp} value={deptId || ""} onChange={(e) => { setDeptId(e.target.value || null); setArrId(null); setCommId(null); }} disabled={!regionId}>
          <option value="">— Département —</option>
          {(departments || []).map((d) => <option key={d.id} value={d.id}>{d.name_fr}</option>)}
        </select>
        <select style={_inp} value={arrId || ""} onChange={(e) => { setArrId(e.target.value || null); setCommId(null); }} disabled={!deptId}>
          <option value="">— Arrondissement —</option>
          {(arrondissements || []).map((a) => <option key={a.id} value={a.id}>{a.name_fr}</option>)}
        </select>
        <select style={_inp} value={commId || ""} onChange={(e) => setCommId(e.target.value || null)} disabled={!arrId}>
          <option value="">— Commune —</option>
          {(communes || []).map((c) => <option key={c.id} value={c.id}>{c.name_fr}</option>)}
        </select>
        <input style={{ ..._inp, minWidth: 140, flex: 1 }} placeholder="🔎 Filtrer…" value={search} onChange={(e) => setSearch(e.target.value)} />
        <span className="text-faint" style={{ fontSize: 12 }}>{rows.length} résultats</span>
        {commId && (
          <button className="btn xs primary" onClick={() => setCreating(true)}>
            <Icon.plus /> {lang === "fr" ? "Nouveau quartier" : "New neighborhood"}
          </button>
        )}
      </div>
      <div className="card-body flush" style={{ maxHeight: "70vh", overflow: "auto" }}>
        {!commId ? (
          <div className="text-faint" style={{ padding: 22, textAlign: "center" }}>{lang === "fr" ? "Choisir une commune." : "Pick a commune."}</div>
        ) : loading ? (
          <div className="text-faint" style={{ padding: 22, textAlign: "center" }}>{lang === "fr" ? "Chargement…" : "Loading…"}</div>
        ) : rows.length === 0 ? (
          <div className="text-faint" style={{ padding: 22, textAlign: "center" }}>
            {lang === "fr" ? "Aucun quartier enregistré. Cliquez « Nouveau quartier » pour démarrer." : "No neighborhood. Click 'New neighborhood' to start."}
          </div>
        ) : (
          <table className="tbl">
            <thead><tr>
              <th>{lang === "fr" ? "Nom" : "Name"}</th>
              <th style={{ width: 60 }}></th>
            </tr></thead>
            <tbody>
              {rows.map((r) => (
                <tr key={r.id}>
                  <td className="strong">{r.name_fr}</td>
                  <td className="num"><button className="iconbtn" onClick={() => setEditing(r)}><Icon.edit /></button></td>
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </div>
      {(creating || editing) && <QuartierModal lang={lang} row={editing} commId={commId} onClose={() => { setEditing(null); setCreating(false); }} onSaved={async () => { setEditing(null); setCreating(false); await refresh(); }} />}
    </div>
  );
}

// ============================================================================
// Modales · création / édition pour chaque niveau
// ============================================================================
function _genericModal(title, fields, onSave, onClose, row) {
  const Modal = window.Modal;
  const [state, setState] = React.useState(() => {
    const init = {};
    fields.forEach((f) => { init[f.key] = (row && row[f.key]) || ""; });
    return init;
  });
  const [busy, setBusy] = React.useState(false);
  const [err, setErr] = React.useState(null);
  const submit = async () => {
    setErr(null); setBusy(true);
    try { await onSave(state); }
    catch (e) { setErr(e.message); setBusy(false); }
  };
  return (
    <Modal title={title} onClose={busy ? null : onClose} size="sm"
      footer={<>
        <button className="btn sm" onClick={onClose} disabled={busy}>Annuler</button>
        <button className="btn sm primary" onClick={submit} disabled={busy}>{busy ? "…" : (row ? "Enregistrer" : "Créer")}</button>
      </>}>
      <div style={{ display: "grid", gap: 10 }}>
        {fields.map((f) => (
          <label key={f.key} style={{ display: "grid", gap: 4 }}>
            <span style={{ fontSize: 11, color: "var(--text-faint)", textTransform: "uppercase", letterSpacing: "0.04em" }}>{f.label}</span>
            <input style={_inp} value={state[f.key] || ""} onChange={(e) => setState((s) => ({ ...s, [f.key]: e.target.value }))} maxLength={f.maxLength || undefined} />
          </label>
        ))}
        {err && <div style={{ color: "#b91c1c", fontSize: 12 }}>{err}</div>}
      </div>
    </Modal>
  );
}

function CountryModal({ lang, row, onClose, onSaved }) {
  return _genericModal(
    lang === "fr" ? (row ? "Modifier le pays" : "Nouveau pays") : (row ? "Edit country" : "New country"),
    [
      { key: "iso2",    label: "ISO2",            maxLength: 2 },
      { key: "name_fr", label: lang === "fr" ? "Nom français" : "French name" },
      { key: "name_en", label: lang === "fr" ? "Nom anglais"  : "English name" },
      { key: "region",  label: lang === "fr" ? "Région ONU"   : "UN region" },
    ],
    async (state) => {
      if (row) await window.melr.countriesCrud.update(row.iso2, state);
      else     await window.melr.countriesCrud.create({ ...state, iso2: (state.iso2 || "").toUpperCase() });
      await onSaved();
    },
    onClose, row
  );
}
function RegionModal({ lang, row, country, onClose, onSaved }) {
  return _genericModal(
    lang === "fr" ? (row ? "Modifier la région" : "Nouvelle région") : (row ? "Edit region" : "New region"),
    [
      { key: "code",    label: "Code" },
      { key: "name_fr", label: lang === "fr" ? "Nom (français)" : "Name (French)" },
      { key: "name_en", label: lang === "fr" ? "Nom (anglais)"  : "Name (English)" },
    ],
    async (state) => {
      if (row) await window.melr.geoRegionsCrud.update(row.id, state);
      else     await window.melr.geoRegionsCrud.create({ ...state, country_iso2: country });
      await onSaved();
    },
    onClose, row
  );
}
function DepartmentModal({ lang, row, regionId, onClose, onSaved }) {
  return _genericModal(
    lang === "fr" ? (row ? "Modifier le département" : "Nouveau département") : (row ? "Edit department" : "New department"),
    [
      { key: "code",    label: "Code" },
      { key: "name_fr", label: lang === "fr" ? "Nom (français)" : "Name (French)" },
      { key: "name_en", label: lang === "fr" ? "Nom (anglais)"  : "Name (English)" },
    ],
    async (state) => {
      if (row) await window.melr.geoDepartmentsCrud.update(row.id, state);
      else     await window.melr.geoDepartmentsCrud.create({ ...state, region_id: regionId });
      await onSaved();
    },
    onClose, row
  );
}
function ArrondissementModal({ lang, row, deptId, onClose, onSaved }) {
  return _genericModal(
    lang === "fr" ? (row ? "Modifier l'arrondissement" : "Nouvel arrondissement") : (row ? "Edit arrondissement" : "New arrondissement"),
    [
      { key: "name_fr", label: lang === "fr" ? "Nom (français)" : "Name (French)" },
      { key: "name_en", label: lang === "fr" ? "Nom (anglais)"  : "Name (English)" },
    ],
    async (state) => {
      if (row) await window.melr.geoArrondissementsCrud.update(row.id, state);
      else     await window.melr.geoArrondissementsCrud.create({ ...state, department_id: deptId });
      await onSaved();
    },
    onClose, row
  );
}
function CommuneModal({ lang, row, arrId, onClose, onSaved }) {
  return _genericModal(
    lang === "fr" ? (row ? "Modifier la commune" : "Nouvelle commune") : (row ? "Edit commune" : "New commune"),
    [
      { key: "name_fr",      label: lang === "fr" ? "Nom (français)" : "Name (French)" },
      { key: "name_en",      label: lang === "fr" ? "Nom (anglais)"  : "Name (English)" },
      { key: "type",         label: lang === "fr" ? "Type"           : "Type" },
      { key: "ville_parent", label: lang === "fr" ? "Ville parent (si commune d'arr.)" : "Parent city (if commune d'arr.)" },
    ],
    async (state) => {
      if (row) await window.melr.geoCommunesCrud.update(row.id, state);
      else     await window.melr.geoCommunesCrud.create({ ...state, arrondissement_id: arrId });
      await onSaved();
    },
    onClose, row
  );
}
function QuartierModal({ lang, row, commId, onClose, onSaved }) {
  return _genericModal(
    lang === "fr" ? (row ? "Modifier le quartier" : "Nouveau quartier") : (row ? "Edit neighborhood" : "New neighborhood"),
    [
      { key: "name_fr", label: lang === "fr" ? "Nom (français)" : "Name (French)" },
      { key: "name_en", label: lang === "fr" ? "Nom (anglais)"  : "Name (English)" },
    ],
    async (state) => {
      if (row) await window.melr.geoQuartiersCrud.update(row.id, state);
      else     await window.melr.geoQuartiersCrud.create({ ...state, commune_id: commId });
      await onSaved();
    },
    onClose, row
  );
}

window.ProjectPlanning = ProjectPlanning;
