/* global React, Icon, window */
// ============================================================================
// MELR · Most Significant Change (MSC) — module Histoires de changement
// ----------------------------------------------------------------------------
// Méthode MSC (Davies & Dart) : collecter des récits qualitatifs de
// changements observés, puis en sélectionner les plus significatifs en
// atelier. Différentiateur fort vs. plateformes M&E purement quantitatives.
//
// v1 (ce fichier) :
//   - Liste des histoires avec filtres (projet, domaine, tags, statut)
//   - Création / édition / suppression
//   - Marquage de sélection + rang + raison
//   - Exports CSV / Word
//
// Layout (sections colorées, alignées sur Learning) :
//   - Toolbar (amber)        · scope + filtres + exports
//   - KPIs (blue)            · total, sélectionnées, contributeurs uniques, domaines
//   - Histoires (green)      · liste + CRUD + sélection
//   - Top sélection (purple) · les histoires marquées avec leur rang
// ============================================================================

(function () {
  const { useState, useMemo, useEffect } = React;

  // ── Constants ───────────────────────────────────────────────────────────
  const STATUS_META = {
    collected: { fr: "Collectée",  en: "Collected", es: "Recopilada",  color: "#2563eb", fill: "#dbeafe" },
    reviewed:  { fr: "Revue",      en: "Reviewed", es: "Revisada",   color: "#7c3aed", fill: "#ede9fe" },
    selected:  { fr: "Sélectionnée", en: "Selected", es: "Seleccionada", color: "#15803d", fill: "#dcfce7" },
    rejected:  { fr: "Rejetée",    en: "Rejected", es: "Rechazada",   color: "#b91c1c", fill: "#fee2e2" },
    archived:  { fr: "Archivée",   en: "Archived", es: "Archivada",   color: "#6b7280", fill: "#f3f4f6" },
  };
  const STATUSES = ["collected", "reviewed", "selected", "rejected", "archived"];

  // ── Small UI helpers ────────────────────────────────────────────────────
  function StatusBadge({ status, lang }) {
    const m = STATUS_META[status] || STATUS_META.collected;
    return (
      <span style={{
        display: "inline-block", padding: "2px 8px", borderRadius: 10,
        background: m.fill, color: m.color, fontSize: 11, fontWeight: 600,
      }}>{(lang === "es" ? (m.es != null ? m.es : m.en) : lang === "fr" ? m.fr : m.en)}</span>
    );
  }

  function TagChip({ tag }) {
    return (
      <span style={{
        display: "inline-block", background: "#ede9fe", color: "#6b21a8",
        padding: "1px 7px", borderRadius: 999, fontSize: 10.5, fontWeight: 500, marginRight: 4,
      }}>#{tag}</span>
    );
  }

  function KpiCard({ label, value, color, hint }) {
    return (
      <div style={{
        background: "var(--bg-elev)", border: "1px solid var(--line)",
        borderRadius: 8, padding: "14px 18px", minWidth: 140, flex: 1,
      }}>
        <div style={{ fontSize: 11, textTransform: "uppercase", letterSpacing: ".5px", color: "var(--muted)", fontWeight: 600 }}>{label}</div>
        <div style={{ fontSize: 28, fontWeight: 800, color: color || "var(--text)", marginTop: 4 }}>{value}</div>
        {hint && <div style={{ fontSize: 11, color: "var(--muted)", marginTop: 4 }}>{hint}</div>}
      </div>
    );
  }

  function sectionStyle(tintHex, borderHex) {
    return {
      background: tintHex, borderLeft: "4px solid " + borderHex,
      padding: "14px 16px", borderRadius: 8, marginBottom: 16,
    };
  }
  function sectionTitleStyle(color) {
    return { fontSize: 14, fontWeight: 700, margin: "0 0 10px", color, display: "flex", alignItems: "center", gap: 8 };
  }

  // ── Main screen ─────────────────────────────────────────────────────────
  function MscScreen({ t, lang }) {
    const { data: storiesRaw, loading, refresh } = window.melr.useMscStories
      ? window.melr.useMscStories()
      : { data: [], loading: false, refresh: () => {} };
    // useProjects() retourne { projects, loading, error, refresh, realtime }
    // — pas { data, ... } — donc destructurer sur `projects` directement.
    const { projects } = window.melr.useProjects ? window.melr.useProjects() : { projects: [] };
    const stories = Array.isArray(storiesRaw) ? storiesRaw : [];

    const [search, setSearch] = useState("");
    const [domain, setDomain] = useState("__all__");
    const [statusFilter, setStatusFilter] = useState("__all__");
    const [projectFilter, setProjectFilter] = useState("__all__");
    const [editing, setEditing] = useState(null);  // story | "new" | null
    const [confirmDel, setConfirmDel] = useState(null);

    // Filtered list
    const filtered = useMemo(() => {
      let r = stories;
      if (statusFilter !== "__all__") r = r.filter((s) => s.status === statusFilter);
      if (domain !== "__all__")       r = r.filter((s) => (s.change_domain || "").toLowerCase() === domain.toLowerCase());
      if (projectFilter !== "__all__") r = r.filter((s) => s.project_id === projectFilter);
      const q = search.trim().toLowerCase();
      if (q) {
        r = r.filter((s) => (s.title || "").toLowerCase().includes(q)
          || (s.narrative || "").toLowerCase().includes(q)
          || (s.contributor_name || "").toLowerCase().includes(q)
          || (s.tags || []).some((tg) => String(tg).toLowerCase().includes(q)));
      }
      return r;
    }, [stories, search, domain, statusFilter, projectFilter]);

    // KPIs
    const kpis = useMemo(() => {
      const selected = stories.filter((s) => s.selected).length;
      const contributors = new Set(stories.map((s) => (s.contributor_name || "").trim()).filter(Boolean));
      const domains = new Set(stories.map((s) => (s.change_domain || "").trim()).filter(Boolean));
      const projectsCovered = new Set(stories.map((s) => s.project_id).filter(Boolean));
      return {
        total: stories.length,
        selected,
        contributors: contributors.size,
        domains: domains.size,
        projects: projectsCovered.size,
      };
    }, [stories]);

    // Unique domain list for dropdown
    const domainOptions = useMemo(() => {
      const set = new Set(stories.map((s) => (s.change_domain || "").trim()).filter(Boolean));
      return Array.from(set).sort();
    }, [stories]);

    // Top sélection : histoires marquées, triées par rang (puis date)
    const topSelected = useMemo(() => {
      return stories
        .filter((s) => s.selected)
        .sort((a, b) => {
          const ra = a.selection_rank == null ? 999 : a.selection_rank;
          const rb = b.selection_rank == null ? 999 : b.selection_rank;
          if (ra !== rb) return ra - rb;
          return new Date(b.story_date || b.created_at) - new Date(a.story_date || a.created_at);
        });
    }, [stories]);

    const onDelete = async (id) => {
      try {
        await window.melr.mscStoriesCrud.remove(id);
        await refresh();
        setConfirmDel(null);
      } catch (e) { alert((window.L("Erreur : ", "Error: ", "Error: ")) + e.message); }
    };

    const projectsById = useMemo(() => {
      const m = {};
      (projects || []).forEach((p) => { m[p.uuid || p.id] = p; });
      return m;
    }, [projects]);

    return (
      <div className="page">
        <div className="page-header">
          <div className="page-eyebrow">{window.L("APPRENTISSAGE QUALITATIF", "QUALITATIVE LEARNING", "APRENDIZAJE CUALITATIVO")}</div>
          <div className="page-header-row">
            <div>
              <h1 className="page-title">{window.L("Histoires de changement (MSC)", "Stories of change (MSC)", "Historias de cambio (MSC)")}</h1>
              <div className="page-sub">
                {window.L("Méthode Most Significant Change : collecter, qualifier et sélectionner les récits de changement les plus significatifs observés sur le terrain.", "Most Significant Change method: collect, qualify, and select the most significant stories of change observed in the field.", "Método Most Significant Change: recopilar, calificar y seleccionar los relatos de cambio más significativos observados sobre el terreno.")}
              </div>
            </div>
            <div className="page-header-actions">
              <button onClick={() => setEditing("new")} className="btn sm primary">
                <Icon.plus /> {window.L("Nouvelle histoire", "New story", "Nueva historia")}
              </button>
            </div>
          </div>
        </div>

        {/* Toolbar (amber) */}
        <div style={sectionStyle("#fffbeb", "#d97706")}>
          <h3 style={sectionTitleStyle("#92400e")}>🔍 {window.L("Filtres", "Filters", "Filtros")}</h3>
          <div style={{ display: "flex", flexWrap: "wrap", gap: 10, alignItems: "center" }}>
            <input type="search" value={search} onChange={(e) => setSearch(e.target.value)}
              placeholder={window.L("Recherche (titre, narrative, contributeur, tag)…", "Search (title, narrative, contributor, tag)…", "Búsqueda (título, narrativa, contribuidor, etiqueta)…")}
              style={{ flex: "1 1 240px", minWidth: 200, padding: "7px 10px", borderRadius: 6, border: "1px solid #fcd34d", background: "white", color: "var(--text)", fontSize: 12.5 }} />
            <select value={statusFilter} onChange={(e) => setStatusFilter(e.target.value)}
              style={{ padding: "7px 10px", borderRadius: 6, border: "1px solid #fcd34d", background: "white", fontSize: 12.5 }}>
              <option value="__all__">{window.L("Tous statuts", "All statuses", "Todos los estados")}</option>
              {STATUSES.map((s) => <option key={s} value={s}>{(lang === "es" ? (STATUS_META[s].es != null ? STATUS_META[s].es : STATUS_META[s].en) : lang === "fr" ? STATUS_META[s].fr : STATUS_META[s].en)}</option>)}
            </select>
            <select value={domain} onChange={(e) => setDomain(e.target.value)}
              style={{ padding: "7px 10px", borderRadius: 6, border: "1px solid #fcd34d", background: "white", fontSize: 12.5 }}>
              <option value="__all__">{window.L("Tous domaines", "All domains", "Todos los dominios")}</option>
              {domainOptions.map((d) => <option key={d} value={d}>{d}</option>)}
            </select>
            <select value={projectFilter} onChange={(e) => setProjectFilter(e.target.value)}
              style={{ padding: "7px 10px", borderRadius: 6, border: "1px solid #fcd34d", background: "white", fontSize: 12.5 }}>
              <option value="__all__">{window.L("Tous projets", "All projects", "Todos los proyectos")}</option>
              {(projects || []).map((p) => <option key={p.uuid || p.id} value={p.uuid || p.id}>{p.name || p.nameFr || p.code}</option>)}
            </select>
            <button onClick={() => exportMscCsv(filtered, projectsById, lang)}
              style={{ padding: "7px 12px", borderRadius: 6, border: "1px solid #16a34a", background: "#16a34a", color: "white", cursor: "pointer", fontWeight: 600, fontSize: 12 }}>
              📊 CSV
            </button>
            <button onClick={() => exportMscDocx(filtered, projectsById, lang)}
              style={{ padding: "7px 12px", borderRadius: 6, border: "1px solid #2563eb", background: "#2563eb", color: "white", cursor: "pointer", fontWeight: 600, fontSize: 12 }}>
              📄 Word
            </button>
          </div>
        </div>

        {/* KPIs (blue) */}
        <div style={sectionStyle("#eff6ff", "#3b82f6")}>
          <h3 style={sectionTitleStyle("#1e40af")}>📊 {window.L("Indicateurs", "Indicators", "Indicadores")}</h3>
          <div style={{ display: "flex", gap: 12, flexWrap: "wrap" }}>
            <KpiCard label={window.L("Histoires", "Stories", "Historias")} value={kpis.total} color="#1e40af" />
            <KpiCard label={window.L("Sélectionnées", "Selected", "Seleccionadas")} value={kpis.selected} color="#15803d" hint={kpis.total ? Math.round(100 * kpis.selected / kpis.total) + " %" : null} />
            <KpiCard label={window.L("Contributeurs", "Contributors", "Contribuidores")} value={kpis.contributors} color="#7c3aed" />
            <KpiCard label={window.L("Domaines", "Domains", "Dominios")} value={kpis.domains} color="#d97706" />
            <KpiCard label={window.L("Projets couverts", "Projects covered", "Proyectos cubiertos")} value={kpis.projects} color="#0f766e" />
          </div>
        </div>

        {/* Stories list (green) */}
        <div style={sectionStyle("#f0fdf4", "#10b981")}>
          <h3 style={sectionTitleStyle("#065f46")}>
            📖 {window.L("Histoires", "Stories", "Historias")} <span style={{ fontWeight: 500, color: "var(--muted)", fontSize: 12 }}>({filtered.length})</span>
          </h3>
          {loading && <div style={{ color: "var(--muted)" }}>{window.L("Chargement…", "Loading…", "Cargando…")}</div>}
          {!loading && filtered.length === 0 && (
            <div style={{ color: "var(--muted)", padding: "12px 0", fontStyle: "italic" }}>
              {window.L("Aucune histoire pour ces filtres. Cliquez « Nouvelle histoire » pour commencer.", "No stories match. Click 'New story' to start.", "No hay historias para estos filtros. Haga clic en «Nueva historia» para empezar.")}
            </div>
          )}
          {!loading && filtered.length > 0 && (
            <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
              {filtered.map((story) => {
                const proj = projectsById[story.project_id];
                return (
                  <div key={story.id} style={{
                    background: "var(--bg-elev)", border: "1px solid var(--line)",
                    borderRadius: 8, padding: "12px 14px",
                  }}>
                    <div style={{ display: "flex", alignItems: "flex-start", justifyContent: "space-between", gap: 12 }}>
                      <div style={{ flex: 1, minWidth: 0 }}>
                        <div style={{ display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap", marginBottom: 6 }}>
                          {story.selected && (
                            <span style={{ background: "#fef3c7", color: "#92400e", padding: "2px 8px", borderRadius: 999, fontSize: 11, fontWeight: 700 }}>
                              ★ {window.L("Sélectionnée", "Selected", "Seleccionada")}
                              {story.selection_rank != null && " #" + story.selection_rank}
                            </span>
                          )}
                          <StatusBadge status={story.status} lang={lang} />
                          {story.change_domain && (
                            <span style={{ background: "#e0f2fe", color: "#075985", padding: "2px 8px", borderRadius: 999, fontSize: 11, fontWeight: 600 }}>
                              {story.change_domain}
                            </span>
                          )}
                          {(story.tags || []).map((tg) => <TagChip key={tg} tag={tg} />)}
                        </div>
                        <div style={{ fontSize: 14, fontWeight: 700, color: "var(--text)", marginBottom: 4 }}>{story.title}</div>
                        <div style={{ fontSize: 12.5, color: "var(--text)", lineHeight: 1.5, whiteSpace: "pre-wrap" }}>
                          {(story.narrative || "").length > 280 ? story.narrative.slice(0, 280) + "…" : story.narrative}
                        </div>
                        <div style={{ display: "flex", flexWrap: "wrap", gap: 12, marginTop: 8, fontSize: 11.5, color: "var(--text-faint)" }}>
                          {story.contributor_name && <span>👤 {story.contributor_name}{story.contributor_role ? " (" + story.contributor_role + ")" : ""}</span>}
                          {story.location && <span>📍 {story.location}</span>}
                          {story.story_date && <span>📅 {new Date(story.story_date).toLocaleDateString(window.L("fr-FR", "en-US", "es-ES"))}</span>}
                          {proj && <span>🎯 {proj.name || proj.nameFr || proj.code}</span>}
                        </div>
                        {story.selection_reason && (
                          <div style={{ marginTop: 8, padding: "8px 10px", background: "#fffbeb", borderLeft: "3px solid #d97706", fontSize: 11.5, fontStyle: "italic", color: "#78350f" }}>
                            {window.L("Motif sélection : ", "Selection reason: ", "Motivo de selección: ")}{story.selection_reason}
                          </div>
                        )}
                      </div>
                      <div style={{ display: "flex", gap: 4, flexShrink: 0 }}>
                        <button onClick={() => setEditing(story)}
                          title={window.L("Modifier", "Edit", "Editar")}
                          style={{ padding: "4px 8px", borderRadius: 4, border: "1px solid var(--line)", background: "var(--bg)", color: "var(--text)", cursor: "pointer", fontSize: 11.5 }}>
                          ✎
                        </button>
                        <button onClick={() => setConfirmDel(story)}
                          title={window.L("Supprimer", "Delete", "Eliminar")}
                          style={{ padding: "4px 8px", borderRadius: 4, border: "1px solid var(--line)", background: "var(--bg)", color: "#dc2626", cursor: "pointer", fontSize: 11.5 }}>
                          🗑
                        </button>
                      </div>
                    </div>
                  </div>
                );
              })}
            </div>
          )}
        </div>

        {/* Top sélection (purple) */}
        <div style={sectionStyle("#faf5ff", "#a855f7")}>
          <h3 style={sectionTitleStyle("#6b21a8")}>
            ★ {window.L("Top sélection", "Top selection", "Selección destacada")} <span style={{ fontWeight: 500, color: "var(--muted)", fontSize: 12 }}>({topSelected.length})</span>
          </h3>
          {topSelected.length === 0 ? (
            <div style={{ color: "var(--muted)", fontStyle: "italic" }}>
              {window.L("Aucune histoire encore sélectionnée. Utilisez le bouton ✎ d'une histoire pour cocher « Sélectionnée » et lui donner un rang.", "No story selected yet. Use the ✎ button on a story to tick 'Selected' and give it a rank.", "Aún no hay ninguna historia seleccionada. Use el botón ✎ de una historia para marcar «Seleccionada» y asignarle un rango.")}
            </div>
          ) : (
            <ol style={{ margin: 0, paddingLeft: 20 }}>
              {topSelected.map((s) => (
                <li key={s.id} style={{ marginBottom: 6, fontSize: 12.5 }}>
                  <strong>{s.title}</strong>
                  {s.change_domain && <span style={{ marginLeft: 6, color: "var(--text-faint)" }}>· {s.change_domain}</span>}
                  {s.contributor_name && <span style={{ marginLeft: 6, color: "var(--text-faint)" }}>· {s.contributor_name}</span>}
                </li>
              ))}
            </ol>
          )}
        </div>

        {editing && (
          <StoryEditor lang={lang} existing={editing === "new" ? null : editing} projects={projects || []}
            onClose={() => setEditing(null)} onSaved={refresh} />
        )}
        {confirmDel && (
          <ConfirmModal lang={lang} story={confirmDel}
            onConfirm={() => onDelete(confirmDel.id)} onCancel={() => setConfirmDel(null)} />
        )}
      </div>
    );
  }

  // ── Editor modal ────────────────────────────────────────────────────────
  function StoryEditor({ lang, existing, projects, onClose, onSaved }) {
    const [title, setTitle] = useState(existing ? existing.title : "");
    const [narrative, setNarrative] = useState(existing ? existing.narrative : "");
    const [changeDomain, setChangeDomain] = useState(existing ? (existing.change_domain || "") : "");
    const [contributorName, setContributorName] = useState(existing ? (existing.contributor_name || "") : "");
    const [contributorRole, setContributorRole] = useState(existing ? (existing.contributor_role || "") : "");
    const [storyDate, setStoryDate] = useState(existing ? (existing.story_date || "") : "");
    const [location, setLocation] = useState(existing ? (existing.location || "") : "");
    const [projectId, setProjectId] = useState(existing ? (existing.project_id || "") : "");
    const [status, setStatus] = useState(existing ? (existing.status || "collected") : "collected");
    const [selected, setSelected] = useState(existing ? !!existing.selected : false);
    const [selectionRank, setSelectionRank] = useState(existing && existing.selection_rank != null ? String(existing.selection_rank) : "");
    const [selectionReason, setSelectionReason] = useState(existing ? (existing.selection_reason || "") : "");
    const [tagsInput, setTagsInput] = useState(existing && existing.tags ? existing.tags.join(", ") : "");
    const [busy, setBusy] = useState(false);
    const [err, setErr] = useState(null);

    const Modal = window.Modal;

    const onSubmit = async (e) => {
      e.preventDefault();
      if (!title.trim()) { setErr(window.L("Titre requis.", "Title required.", "Título obligatorio.")); return; }
      if (!narrative.trim()) { setErr(window.L("Récit requis.", "Narrative required.", "Relato obligatorio.")); return; }
      setBusy(true); setErr(null);
      try {
        const tags = tagsInput.split(",").map((s) => s.trim()).filter(Boolean);
        const rank = selectionRank.trim() ? parseInt(selectionRank, 10) : null;
        const payload = {
          title: title.trim(),
          narrative: narrative.trim(),
          change_domain: changeDomain.trim() || null,
          contributor_name: contributorName.trim() || null,
          contributor_role: contributorRole.trim() || null,
          story_date: storyDate || null,
          location: location.trim() || null,
          project_id: projectId || null,
          status,
          selected,
          selection_rank: selected && !isNaN(rank) ? rank : null,
          selection_reason: selected ? (selectionReason.trim() || null) : null,
          tags,
        };
        if (existing) await window.melr.mscStoriesCrud.update(existing.id, payload);
        else          await window.melr.mscStoriesCrud.create(payload);
        await onSaved();
        onClose();
      } catch (e) {
        setErr(e.message || String(e));
      } finally {
        setBusy(false);
      }
    };

    const inp = { width: "100%", padding: "8px 10px", borderRadius: 6, border: "1px solid var(--line)", background: "var(--bg)", color: "var(--text)", boxSizing: "border-box", fontSize: 13 };
    const lbl = { display: "block", fontSize: 12, fontWeight: 600, marginBottom: 4, color: "var(--text)" };

    return (
      <Modal lang={lang}
        title={existing ? (window.L("Modifier l'histoire", "Edit story", "Editar la historia")) : (window.L("Nouvelle histoire de changement", "New story of change", "Nueva historia de cambio"))}
        onClose={onClose}>
        <form onSubmit={onSubmit} style={{ display: "flex", flexDirection: "column", gap: 12 }}>
          <div>
            <label style={lbl}>{window.L("Titre", "Title", "Título")} *</label>
            <input value={title} onChange={(e) => setTitle(e.target.value)} required style={inp}
              placeholder={window.L("Une coopérative reprend le contrôle de son cycle de crédit", "A cooperative regains control of its credit cycle", "Una cooperativa recupera el control de su ciclo de crédito")} />
          </div>
          <div>
            <label style={lbl}>{window.L("Récit", "Narrative", "Relato")} *</label>
            <textarea value={narrative} onChange={(e) => setNarrative(e.target.value)} required rows={8} style={{ ...inp, fontFamily: "inherit" }}
              placeholder={window.L("Que s'est-il passé ? Pour qui ? Pourquoi est-ce important ? Quel était l'état avant ? Quel est-il aujourd'hui ?", "What happened? For whom? Why is it important? What was the state before? What is it now?", "¿Qué ocurrió? ¿Para quién? ¿Por qué es importante? ¿Cuál era la situación antes? ¿Cuál es ahora?")} />
          </div>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 }}>
            <div>
              <label style={lbl}>{window.L("Domaine de changement", "Change domain", "Dominio de cambio")}</label>
              <input value={changeDomain} onChange={(e) => setChangeDomain(e.target.value)} style={inp}
                placeholder={window.L("Genre, Gouvernance, Santé, …", "Gender, Governance, Health, …", "Género, Gobernanza, Salud, …")} />
            </div>
            <div>
              <label style={lbl}>{window.L("Projet rattaché", "Linked project", "Proyecto vinculado")}</label>
              <select value={projectId} onChange={(e) => setProjectId(e.target.value)} style={inp}>
                <option value="">{window.L("— Aucun —", "— None —", "— Ninguno —")}</option>
                {projects.map((p) => <option key={p.uuid || p.id} value={p.uuid || p.id}>{p.name || p.nameFr || p.code}</option>)}
              </select>
            </div>
          </div>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 }}>
            <div>
              <label style={lbl}>{window.L("Contributeur (nom)", "Contributor (name)", "Contribuidor (nombre)")}</label>
              <input value={contributorName} onChange={(e) => setContributorName(e.target.value)} style={inp} />
            </div>
            <div>
              <label style={lbl}>{window.L("Rôle", "Role", "Rol")}</label>
              <input value={contributorRole} onChange={(e) => setContributorRole(e.target.value)} style={inp}
                placeholder={window.L("Bénéficiaire / Agent / …", "Beneficiary / Officer / …", "Beneficiario / Agente / …")} />
            </div>
          </div>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 12 }}>
            <div>
              <label style={lbl}>{window.L("Date du changement", "Date of change", "Fecha del cambio")}</label>
              <input type="date" value={storyDate} onChange={(e) => setStoryDate(e.target.value)} style={inp} />
            </div>
            <div>
              <label style={lbl}>{window.L("Lieu", "Location", "Lugar")}</label>
              <input value={location} onChange={(e) => setLocation(e.target.value)} style={inp} />
            </div>
            <div>
              <label style={lbl}>{window.L("Statut", "Status", "Estado")}</label>
              <select value={status} onChange={(e) => setStatus(e.target.value)} style={inp}>
                {STATUSES.map((s) => <option key={s} value={s}>{(lang === "es" ? (STATUS_META[s].es != null ? STATUS_META[s].es : STATUS_META[s].en) : lang === "fr" ? STATUS_META[s].fr : STATUS_META[s].en)}</option>)}
              </select>
            </div>
          </div>
          <div>
            <label style={lbl}>{window.L("Tags (séparés par virgule)", "Tags (comma-separated)", "Etiquetas (separadas por comas)")}</label>
            <input value={tagsInput} onChange={(e) => setTagsInput(e.target.value)} style={inp}
              placeholder="femme, jeune, handicap" />
          </div>

          {/* Sélection */}
          <div style={{ padding: 10, background: "#fffbeb", borderRadius: 6, border: "1px solid #fcd34d" }}>
            <label style={{ display: "flex", alignItems: "center", gap: 8, fontWeight: 600, fontSize: 13, color: "#92400e" }}>
              <input type="checkbox" checked={selected} onChange={(e) => setSelected(e.target.checked)} />
              ★ {window.L("Cette histoire est sélectionnée (atelier MSC)", "This story is selected (MSC workshop)", "Esta historia está seleccionada (taller MSC)")}
            </label>
            {selected && (
              <div style={{ marginTop: 10, display: "grid", gridTemplateColumns: "120px 1fr", gap: 10 }}>
                <div>
                  <label style={lbl}>{window.L("Rang", "Rank", "Rango")}</label>
                  <input type="number" min="1" value={selectionRank} onChange={(e) => setSelectionRank(e.target.value)} style={inp} />
                </div>
                <div>
                  <label style={lbl}>{window.L("Motif de sélection", "Selection reason", "Motivo de selección")}</label>
                  <input value={selectionReason} onChange={(e) => setSelectionReason(e.target.value)} style={inp}
                    placeholder={window.L("Pourquoi le jury a retenu cette histoire", "Why the jury picked this story", "Por qué el jurado eligió esta historia")} />
                </div>
              </div>
            )}
          </div>

          {err && <div style={{ color: "#dc2626", fontSize: 12.5 }}>{err}</div>}
          <div style={{ display: "flex", gap: 8, justifyContent: "flex-end" }}>
            <button type="button" onClick={onClose} disabled={busy}
              style={{ padding: "8px 14px", borderRadius: 6, border: "1px solid var(--line)", background: "var(--bg)", color: "var(--text)", cursor: "pointer" }}>
              {window.L("Annuler", "Cancel", "Cancelar")}
            </button>
            <button type="submit" disabled={busy} className="btn primary">
              {busy ? (window.L("Enregistrement…", "Saving…", "Guardando…")) : (window.L("Enregistrer", "Save", "Guardar"))}
            </button>
          </div>
        </form>
      </Modal>
    );
  }

  function ConfirmModal({ lang, story, onConfirm, onCancel }) {
    const Modal = window.Modal;
    return (
      <Modal lang={lang} title={window.L("Confirmer la suppression", "Confirm deletion", "Confirmar la eliminación")} onClose={onCancel}>
        <div style={{ marginBottom: 16 }}>
          {window.L("Cette histoire sera supprimée définitivement. Continuer ?", "This story will be permanently deleted. Continue?", "Esta historia se eliminará de forma permanente. ¿Continuar?")}
          <div style={{ marginTop: 10, padding: 10, background: "var(--bg-sunken)", borderRadius: 6, fontStyle: "italic" }}>
            « {story.title} »
          </div>
        </div>
        <div style={{ display: "flex", gap: 8, justifyContent: "flex-end" }}>
          <button onClick={onCancel} style={{ padding: "8px 14px", borderRadius: 6, border: "1px solid var(--line)", background: "var(--bg)", color: "var(--text)", cursor: "pointer" }}>
            {window.L("Annuler", "Cancel", "Cancelar")}
          </button>
          <button onClick={onConfirm} style={{ padding: "8px 14px", borderRadius: 6, border: "1px solid #dc2626", background: "#dc2626", color: "white", cursor: "pointer", fontWeight: 600 }}>
            {window.L("Supprimer", "Delete", "Eliminar")}
          </button>
        </div>
      </Modal>
    );
  }

  // ── Exports ─────────────────────────────────────────────────────────────
  function csvEscape(s) {
    const v = s == null ? "" : String(s);
    return /[",\n;]/.test(v) ? "\"" + v.replace(/"/g, "\"\"") + "\"" : v;
  }
  function exportMscCsv(rows, projectsById, lang) {
    const header = lang === "fr"
      ? ["Titre", "Récit", "Domaine", "Statut", "Sélectionnée", "Rang", "Motif", "Contributeur", "Rôle", "Date", "Lieu", "Projet", "Tags"]
      : ["Title", "Narrative", "Domain", "Status", "Selected", "Rank", "Reason", "Contributor", "Role", "Date", "Location", "Project", "Tags"];
    const lines = [header.join(",")];
    rows.forEach((s) => {
      const proj = projectsById[s.project_id];
      lines.push([
        csvEscape(s.title), csvEscape(s.narrative), csvEscape(s.change_domain || ""),
        csvEscape(s.status || ""), s.selected ? "1" : "0", s.selection_rank != null ? String(s.selection_rank) : "",
        csvEscape(s.selection_reason || ""), csvEscape(s.contributor_name || ""), csvEscape(s.contributor_role || ""),
        s.story_date || "", csvEscape(s.location || ""),
        csvEscape(proj ? (proj.name || proj.nameFr || proj.code || "") : ""),
        csvEscape((s.tags || []).join("; ")),
      ].join(","));
    });
    const blob = new Blob(["﻿" + lines.join("\n")], { type: "text/csv;charset=utf-8" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a"); a.href = url;
    a.download = "msc-histoires-" + new Date().toISOString().slice(0, 10) + ".csv";
    document.body.appendChild(a); a.click(); a.remove();
    URL.revokeObjectURL(url);
  }

  async function exportMscDocx(rows, projectsById, lang) {
    if (!window.docx) { alert(window.L("Module docx indisponible.", "docx module unavailable.", "Módulo docx no disponible.")); return; }
    const { Document, Packer, Paragraph, TextRun, HeadingLevel, AlignmentType } = window.docx;
    const children = [];
    children.push(new Paragraph({
      alignment: AlignmentType.CENTER, spacing: { after: 200 },
      children: [new TextRun({ text: window.L("Histoires de changement (MSC)", "Stories of change (MSC)", "Historias de cambio (MSC)"), bold: true, size: 36, color: "6b21a8" })],
    }));
    children.push(new Paragraph({
      alignment: AlignmentType.CENTER, spacing: { after: 400 },
      children: [new TextRun({ text: new Date().toLocaleDateString(window.L("fr-FR", "en-US", "es-ES")), italics: true, color: "6b7280" })],
    }));
    rows.forEach((s) => {
      const proj = projectsById[s.project_id];
      children.push(new Paragraph({
        heading: HeadingLevel.HEADING_2,
        children: [new TextRun({ text: (s.selected ? "★ " : "") + s.title, bold: true })],
        spacing: { before: 240, after: 80 },
      }));
      const meta = [];
      if (s.change_domain)     meta.push(s.change_domain);
      if (proj)                meta.push(proj.name || proj.nameFr || proj.code);
      if (s.location)          meta.push(s.location);
      if (s.story_date)        meta.push(new Date(s.story_date).toLocaleDateString(window.L("fr-FR", "en-US", "es-ES")));
      if (s.contributor_name)  meta.push(s.contributor_name + (s.contributor_role ? " (" + s.contributor_role + ")" : ""));
      children.push(new Paragraph({
        spacing: { after: 120 },
        children: [new TextRun({ text: meta.join(" · "), italics: true, color: "6b7280", size: 18 })],
      }));
      children.push(new Paragraph({
        spacing: { after: 200 },
        children: [new TextRun({ text: s.narrative })],
      }));
      if (s.selected && s.selection_reason) {
        children.push(new Paragraph({
          spacing: { after: 200 },
          children: [new TextRun({ text: (window.L("Motif de sélection : ", "Selection reason: ", "Motivo de la selección: ")) + s.selection_reason, italics: true })],
        }));
      }
    });
    const doc = new Document({
      creator: "MELR · REFT Africa",
      title: window.L("MSC — Histoires de changement", "MSC — Stories of change", "MSC — Historias de cambio"),
      styles: { default: { document: { run: { font: "Calibri", size: 22 } } } },
      sections: [{ children }],
    });
    const blob = await Packer.toBlob(doc);
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a"); a.href = url;
    a.download = "msc-histoires-" + new Date().toISOString().slice(0, 10) + ".docx";
    document.body.appendChild(a); a.click(); a.remove();
    URL.revokeObjectURL(url);
  }

  window.MscScreen = MscScreen;
})();
