<dialog id="propose-modal" aria-label="Qualifier la proposition" data-step="1">
  <form method="dialog" class="box">
    <header class="hd">
      <h2>Qualifier la proposition</h2>
      <button value="cancel" class="x" aria-label="Fermer">✕</button>
    </header>

    <!-- STEP 1 -->
    <section class="step step-1" aria-label="Choisir le type">
      <p class="sub">
        D’abord : quel type de ticket veux-tu ouvrir ?
      </p>

      <div class="grid">
        <button type="button" data-kind="correction">✍️ Correction (rédaction / clarté)</button>
        <button type="button" data-kind="fact">🔎 Vérification factuelle / sources</button>
      </div>

      <footer class="ft">
        <small>Étape 1/2 — <kbd>Esc</kbd> pour fermer.</small>
      </footer>
    </section>

    <!-- STEP 2 -->
    <section class="step step-2" aria-label="Choisir la catégorie">
      <p class="sub">
        Optionnel : choisis une intention (pour tri & traitement éditorial). Sinon, continue sans préciser.
      </p>

      <div class="grid">
        <button type="button" data-category="cat/style">Style / lisibilité</button>
        <button type="button" data-category="cat/lexique">Lexique / terminologie</button>
        <button type="button" data-category="cat/argument">Argument / structure</button>
        <button type="button" data-category="cat/redondance">Redondance</button>
        <button type="button" data-category="cat/source">Source / vérification</button>
        <button type="button" data-category="">Continuer sans préciser</button>
      </div>

      <footer class="ft row">
        <button type="button" class="back" data-back="1">← Retour</button>
        <small>Étape 2/2 — <kbd>Esc</kbd> pour fermer.</small>
      </footer>
    </section>
  </form>
</dialog>

<style>
  dialog { border: none; padding: 0; border-radius: 18px; width: min(760px, calc(100vw - 2rem)); }
  dialog::backdrop { background: rgba(0,0,0,.55); }

  .box { padding: 1rem 1rem .85rem; }
  .hd { display:flex; align-items:center; justify-content:space-between; gap:.75rem; }
  .hd h2 { margin:0; font-size:1.1rem; }
  .x { border:0; background:transparent; font-size:1.1rem; cursor:pointer; }

  .sub { margin:.55rem 0 1rem; opacity:.92; line-height: 1.35; }

  .grid { display:grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap:.55rem; }
  .grid button {
    padding: .8rem .9rem;
    border-radius: 14px;
    border: 1px solid rgba(0,0,0,.18);
    background: rgba(255,255,255,.96);
    color: #111;
    cursor: pointer;
    text-align: left;
    line-height: 1.2;
  }
  .grid button:hover { background: #fff; }

  .ft { margin-top:.85rem; opacity:.88; }
  .ft.row { display:flex; align-items:center; justify-content:space-between; gap:1rem; }
  .back {
    border: 1px solid rgba(0,0,0,.18);
    background: rgba(255,255,255,.96);
    color:#111;
    border-radius: 12px;
    padding: .55rem .7rem;
    cursor: pointer;
  }
  kbd { padding:0 .35rem; border:1px solid rgba(0,0,0,.2); border-radius:6px; }

  .step { display:none; }
  dialog[data-step="1"] .step-1 { display:block; }
  dialog[data-step="2"] .step-2 { display:block; }
</style>

<script is:inline>
(() => {
  const dlg = document.getElementById("propose-modal");
  if (!dlg) return;

  /** @type {URL|null} */
  let pending = null;
  /** @type {"correction"|"fact"|""} */
  let kind = "";

  // Doit rester cohérent avec EditionLayout
  const URL_HARD_LIMIT = 6500;

  const esc = (s) => String(s).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");

  const upsertLine = (text, key, value) => {
    const re = new RegExp(`^\\s*${esc(key)}\\s*:\\s*.*$`, "mi");

    // value vide => supprimer la ligne si elle existe
    if (!value) {
      if (!re.test(text)) return text;
      return (
        text
          .replace(re, "")
          .replace(/\n{3,}/g, "\n\n")
          .trimEnd() + "\n"
      );
    }

    // remplace si existe
    if (re.test(text)) return text.replace(re, `${key}: ${value}`);

    // sinon append
    const sep = text && !text.endsWith("\n") ? "\n" : "";
    return text + sep + `${key}: ${value}\n`;
  };

  const setTitlePrefix = (u, prefix) => {
    const t = u.searchParams.get("title") || "";
    const cleaned = t.replace(/^\[[^\]]+\]\s*/,"");
    u.searchParams.set("title", `[${prefix}] ${cleaned}`.trim());
  };

  const tryUpgradeBodyWithFull = (u, full) => {
    if (!full) return;

    let body = u.searchParams.get("body") || "";
    if (!body) return;

    // Si déjà en "copie exacte", rien à faire
    if (body.includes("Texte actuel (copie exacte du paragraphe)")) return;

    // On ne tente que si le body est en mode extrait
    if (!body.includes("Texte actuel (extrait):")) return;

    const quoted = full.split(/\r?\n/).map(l => `> ${l}`.trimEnd()).join("\n");

    // Remplace le bloc "Texte actuel (extrait)" jusqu'à "Proposition (remplacer par):"
    const re = /Texte actuel \(extrait\):[\s\S]*?\n\nProposition \(remplacer par\):/m;
    const next = body.replace(
      re,
      `Texte actuel (copie exacte du paragraphe):\n${quoted}\n\nProposition (remplacer par):`
    );

    if (next === body) return;

    u.searchParams.set("body", next);

    // garde-fou URL
    if (u.toString().length > URL_HARD_LIMIT) {
      // revert
      u.searchParams.set("body", body);
    }
  };

  // ✅ Ouvre EN NOUVEL ONGLET : stratégie unique (anchor click) => jamais 2 onglets
  const openInNewTab = (url) => {
    try {
      const a = document.createElement("a");
      a.href = url;
      a.target = "_blank";
      a.rel = "noopener noreferrer";
      a.style.display = "none";
      document.body.appendChild(a);
      a.click();
      a.remove();
      return true;
    } catch {}

    // dernier recours
    window.prompt("Popup bloquée. Copiez ce lien pour ouvrir le ticket :", url);
    return false;
  };

  const openWith = (url) => {
    pending = url;
    kind = "";
    dlg.dataset.step = "1";
    if (typeof dlg.showModal === "function") dlg.showModal();
    else openInNewTab(url.toString());
  };

  // Intercepte UNIQUEMENT les liens marqués data-propose
  document.addEventListener("click", async (e) => {
    const a = e.target?.closest?.("a[data-propose]");
    if (!a) return;

    e.preventDefault();
    e.stopImmediatePropagation();

    const rawUrl = a.dataset.url || a.getAttribute("href") || "";
    if (!rawUrl || rawUrl === "#") return;

    const full = (a.dataset.full || "").trim();

    try {
      const u = new URL(rawUrl);

      if (full) {
        try { await navigator.clipboard.writeText(full); } catch {}
        tryUpgradeBodyWithFull(u, full);
      }

      openWith(u);
    } catch {
      openInNewTab(rawUrl);
    }
  }, { capture: true });

  // Step 1: type
  dlg.addEventListener("click", (e) => {
    const btn = e.target?.closest?.("button[data-kind]");
    if (!btn || !pending) return;

    kind = btn.getAttribute("data-kind") || "";
    let body = pending.searchParams.get("body") || "";

    if (kind === "fact") {
      body = upsertLine(body, "Type", "type/fact-check");
      body = upsertLine(body, "State", "state/a-sourcer");
      setTitlePrefix(pending, "Fact-check");
    } else {
      body = upsertLine(body, "Type", "type/correction");
      body = upsertLine(body, "State", "state/recevable");
      setTitlePrefix(pending, "Correction");
    }

    pending.searchParams.set("body", body);
    dlg.dataset.step = "2";
  });

  // Back
  dlg.addEventListener("click", (e) => {
    const back = e.target?.closest?.("button[data-back]");
    if (!back) return;
    dlg.dataset.step = "1";
  });

  // Step 2: category + open
  dlg.addEventListener("click", (e) => {
    const btn = e.target?.closest?.("button[data-category]");
    if (!btn || !pending) return;

    const cat = btn.getAttribute("data-category") || "";
    let body = pending.searchParams.get("body") || "";
    body = upsertLine(body, "Category", cat);
    pending.searchParams.set("body", body);

    const u = pending.toString();
    dlg.close();

    // ✅ ouvre en nouvel onglet, sans jamais remplacer l’onglet courant
    openInNewTab(u);
  });
})();
</script>

