// ui.jsx — primitives partagées (icônes UI simples, boutons, pastilles, logo)
const { useState, useEffect, useRef } = React;

// Jeu d'icônes : traits géométriques simples (UI, pas de l'illustration)
const ICONS = {
  check: "M4 11l4.5 4.5L18 5",
  arrowR: "M5 11h12M12 6l5 5-5 5",
  arrowL: "M17 11H5M10 6l-5 5 5 5",
  plus: "M11 4v14M4 11h14",
  doc: "M6 3h7l4 4v12H6zM13 3v4h4",
  scan: "M4 7V4h3M15 4h3v3M18 15v3h-3M7 18H4v-3M7 11h8",
  auto: "M11 3l1.6 4.4L17 9l-4.4 1.6L11 15l-1.6-4.4L5 9l4.4-1.6z", // étincelle ~ losange
  flag: "M5 3v15M5 4h9l-1.5 3L14 10H5",
  download: "M11 4v9m0 0l-4-4m4 4l4-4M4 17h14",
  shield: "M11 3l6 2v5c0 4-3 6.5-6 7.5C8 16.5 5 14 5 10V5z",
  info: "M11 7h.01M10 10h1v5h1",
  building: "M5 18V5h7v13M12 9h4v9M8 8h1M8 11h1M8 14h1",
  chevR: "M9 6l5 5-5 5",
  chevD: "M6 9l5 5 5-5",
  upload: "M11 16V7m0 0L7 11m4-4l4 4M4 4h14",
  edit: "M13 4l4 4M4 17l1-4 9-9 3 3-9 9z",
  user: "M11 11a3.2 3.2 0 100-6.4A3.2 3.2 0 0011 11zM4.5 18a6.5 6.5 0 0113 0",
  lock: "M6 10V7a5 5 0 0110 0v3M5 10h12v8H5z",
  clock: "M11 5v6l4 2M11 19a8 8 0 100-16 8 8 0 000 16z",
  search: "M10 16a6 6 0 100-12 6 6 0 000 12zM15 15l4 4",
};

function Icon({ name, size = 22, className = "", strokeWidth = 1.6 }) {
  const d = ICONS[name];
  return (
    <svg className={"ic " + className} width={size} height={size} viewBox="0 0 22 22"
      fill="none" stroke="currentColor" strokeWidth={strokeWidth}
      strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
      <path d={d} />
    </svg>
  );
}

// Marque : losange + feuille stylisée minimale (formes simples)
function Logo({ size = 30 }) {
  return (
    <span className="logo">
      <svg width={size} height={size} viewBox="0 0 32 32" aria-hidden="true">
        <rect x="2" y="2" width="28" height="28" rx="8" fill="var(--ink)" />
        <path d="M16 9c-3.4 0-6 2.6-6 6.2 0 3.2 2.6 6 6 7.8 3.4-1.8 6-4.6 6-7.8C22 11.6 19.4 9 16 9z"
          fill="none" stroke="var(--gold)" strokeWidth="1.8" />
        <path d="M16 12v9" stroke="var(--gold)" strokeWidth="1.8" strokeLinecap="round" />
      </svg>
      <span className="logo-word">Grant<span className="logo-word-accent">4</span>me</span>
    </span>
  );
}

function Btn({ children, kind = "primary", icon, iconAfter, onClick, type = "button", full, disabled, size }) {
  return (
    <button type={type} onClick={onClick} disabled={disabled}
      className={"btn btn-" + kind + (full ? " btn-full" : "") + (size === "lg" ? " btn-lg" : "")}>
      {icon && <Icon name={icon} size={size === "lg" ? 22 : 19} />}
      <span>{children}</span>
      {iconAfter && <Icon name={iconAfter} size={size === "lg" ? 22 : 19} />}
    </button>
  );
}

// Pastille de statut (champs + demandes)
const STATUS_META = {
  auto: { label: "Rempli pour vous", tone: "green", icon: "check" },
  confirm: { label: "À confirmer", tone: "gold", icon: "flag" },
  fourni: { label: "Fourni", tone: "green", icon: "check" },
  a_fournir: { label: "À fournir", tone: "gold", icon: "flag" },
  a_completer: { label: "À compléter", tone: "gold", icon: "edit" },
  soumis: { label: "Soumis", tone: "ink", icon: "check" },
  brouillon: { label: "Brouillon", tone: "muted", icon: "edit" },
};

function Pill({ status, label, tone, icon, small }) {
  const m = STATUS_META[status] || {};
  const t = tone || m.tone || "muted";
  return (
    <span className={"pill pill-" + t + (small ? " pill-sm" : "")}>
      {(icon || m.icon) && <Icon name={icon || m.icon} size={small ? 13 : 15} strokeWidth={2} />}
      {label || (m.label && I18N.t(m.label))}
    </span>
  );
}

// Guide « où trouver cette information » — clé de l'accompagnement PME.
// guide = { titre, t }  OU  children libres.
function HelpNote({ children, guide, label }) {
  const [open, setOpen] = useState(false);
  return (
    <span className="help-wrap">
      <button type="button" className={"help-btn" + (open ? " on" : "")}
        aria-label={I18N.t("Aide : ") + (guide ? guide.titre : (label || I18N.t("où trouver cette information")))}
        onClick={() => setOpen((o) => !o)}>
        <Icon name="info" size={15} strokeWidth={2} />
      </button>
      {open && (
        <span className="help-pop">
          {guide ? (
            <>
              <span className="help-pop-h"><Icon name="search" size={13} strokeWidth={2.2} /> {guide.titre}</span>
              <span className="help-pop-t">{guide.t}</span>
            </>
          ) : children}
        </span>
      )}
    </span>
  );
}

// Autocomplete contre un référentiel (lookup_referentiel) — ex. CAE codes.
// search(q) -> [{code, libelle}] ; onPick(match) remplit code+libellé.
function Autocomplete({ value, onChange, onPick, search, placeholder, ariaLabel, footHint }) {
  const [open, setOpen] = useState(false);
  const [hl, setHl] = useState(0);
  const q = (value || "").trim();
  const matches = open && q ? search(q) : [];

  const pick = (m) => { onPick(m); setOpen(false); };
  const onKey = (e) => {
    if (!open || !matches.length) return;
    if (e.key === "ArrowDown") { e.preventDefault(); setHl((h) => Math.min(h + 1, matches.length - 1)); }
    else if (e.key === "ArrowUp") { e.preventDefault(); setHl((h) => Math.max(h - 1, 0)); }
    else if (e.key === "Enter") { e.preventDefault(); pick(matches[hl]); }
    else if (e.key === "Escape") { setOpen(false); }
  };

  return (
    <span className="ac-wrap">
      <input className="pf-input" value={value} placeholder={placeholder} aria-label={ariaLabel}
        autoComplete="off" role="combobox" aria-expanded={open && matches.length > 0}
        onChange={(e) => { onChange(e.target.value); setOpen(true); setHl(0); }}
        onFocus={() => setOpen(true)} onKeyDown={onKey}
        onBlur={() => setTimeout(() => setOpen(false), 130)} />
      {open && q && (
        <span className="ac-pop" role="listbox">
          {matches.length ? matches.map((m, i) => (
            <span key={m.code} className={"ac-item" + (i === hl ? " hl" : "")} role="option" aria-selected={i === hl}
              onMouseDown={(e) => { e.preventDefault(); pick(m); }} onMouseEnter={() => setHl(i)}>
              <span className="ac-code">{m.code}</span>
              <span className="ac-lib">{m.libelle}</span>
            </span>
          )) : <span className="ac-empty">{I18N.t("Aucun résultat pour « {q} »", { q })}</span>}
          {footHint && matches.length > 0 && <span className="ac-foot">{footHint}</span>}
        </span>
      )}
    </span>
  );
}
function FormPagePlaceholder({ label = "page du formulaire", filled = 0 }) {
  return (
    <div className="pageph" role="img" aria-label={label}>
      <div className="pageph-head">
        <div className="pageph-band" />
        {/* L'aperçu de page ne nomme plus un programme précis : le tampon
            reprend le mot du domaine actif. */}
        <div className="pageph-stamp">{I18N.L("formulaire").toUpperCase()}</div>
      </div>
      {Array.from({ length: 9 }).map((_, i) => (
        <div className="pageph-row" key={i}>
          <div className="pageph-lab" />
          <div className={"pageph-fld" + (i < filled ? " on" : "")} />
        </div>
      ))}
      <div className="pageph-foot">{label}</div>
    </div>
  );
}

Object.assign(window, { Icon, Logo, Btn, Pill, HelpNote, Autocomplete, FormPagePlaceholder, STATUS_META });
