// generator-color-patch.jsx — expands brand palette + injects color fields across ALL templates
// runs AFTER templates*.jsx files, BEFORE generator-app.jsx

(function () {
  if (!window.LIROU_TEMPLATES) return;

  // Paleta oficial Lirou Closet 65 — só as cores da marca
  const FULL_PALETTE = [
    "#eadcbe", // cream (fundo principal)
    "#f4f1ec", // paper (fundo claro alternativo)
    "#ffffff", // white
    "#1b1b1a", // ink (texto principal)
    "#674689", // purple (cor de marca)
    "#df4b5a", // coral (destaque / promo)
  ];

  // Defaults pra cada chave de cor reconhecida
  const COLOR_KEY_DEFAULTS = {
    bg:        { label: "Cor de fundo",       def: "#eadcbe" },
    fg:        { label: "Cor do texto",       def: "#1b1b1a" },
    accent:    { label: "Cor de destaque",    def: "#674689" },
    glyph:     { label: "Cor do glifo",       def: "#674689" },
    btn:       { label: "Cor do botão",       def: "#674689" },
    btnText:   { label: "Texto do botão",     def: "#ffffff" },
    hookColor: { label: "Cor do hook",        def: "#df4b5a" },
    textColor: { label: "Cor do texto (logo)", def: "" },
  };

  // 1) expande as options de TODA field do tipo "color" pra paleta completa
  // 2) injeta campos faltantes (fg, accent, btn, btnText, glyph) em todo template
  for (const t of window.LIROU_TEMPLATES) {
    if (!t.fields) continue;
    // Adesivos pra impressão: edição mínima — não injeta campos extras
    if (t.skipColorPatch || (t.group || "").startsWith("Adesivos")) {
      for (const f of t.fields) {
        if (f.type === "color") f.options = FULL_PALETTE.slice();
      }
      continue;
    }
    const present = new Set(t.fields.filter(f => f.type === "color").map(f => f.k));

    // expandir options das que já existem
    for (const f of t.fields) {
      if (f.type === "color") f.options = FULL_PALETTE.slice();
    }

    // injetar campos faltantes — só se o template não tiver
    const inject = [];
    if (!present.has("bg"))      inject.push({ k: "bg",      label: COLOR_KEY_DEFAULTS.bg.label,      type: "color", options: FULL_PALETTE.slice() });
    if (!present.has("fg"))      inject.push({ k: "fg",      label: COLOR_KEY_DEFAULTS.fg.label,      type: "color", options: FULL_PALETTE.slice() });
    if (!present.has("accent"))  inject.push({ k: "accent",  label: COLOR_KEY_DEFAULTS.accent.label,  type: "color", options: FULL_PALETTE.slice() });
    if (!present.has("btn"))     inject.push({ k: "btn",     label: COLOR_KEY_DEFAULTS.btn.label,     type: "color", options: FULL_PALETTE.slice() });
    if (!present.has("btnText")) inject.push({ k: "btnText", label: COLOR_KEY_DEFAULTS.btnText.label, type: "color", options: FULL_PALETTE.slice() });

    if (inject.length) t.fields = t.fields.concat(inject);

    // garantir defaults
    t.defaults = t.defaults || {};
    for (const f of t.fields) {
      if (f.type === "color" && (t.defaults[f.k] === undefined || t.defaults[f.k] === "")) {
        const seed = COLOR_KEY_DEFAULTS[f.k]?.def;
        if (seed) t.defaults[f.k] = seed;
        else t.defaults[f.k] = FULL_PALETTE[0];
      }
    }
  }

  // 3) Wrappa render() pra repassar btn/btnText pros componentes que usem,
  //    sem precisar reescrever cada template — eles já leem d.btn / d.btnText
  //    quando fornecidos via wrapper de estilo abaixo (CSS-vars no canvas).
  //    TAMBÉM: passa por stripEmpty pra remover qualquer elemento de texto vazio.

  // Recursivamente remove elementos cujo único conteúdo é string vazia/whitespace.
  // Mantém imagens, SVGs, BR, HR e divs decorativas (que nunca tiveram filhos de texto).
  // Mantém elementos com dangerouslySetInnerHTML.
  function stripEmpty(el) {
    if (el == null || el === false || el === true) return null;
    if (typeof el === "string") return el.trim() === "" ? null : el;
    if (typeof el === "number") return el;
    if (Array.isArray(el)) {
      const arr = el.map(stripEmpty).filter(c => c !== null && c !== "");
      return arr.length === 0 ? null : arr;
    }
    if (!React.isValidElement(el)) return el;

    // Imagens, SVGs, brs, hrs e elementos com innerHTML manual — preserva
    if (el.props && el.props.dangerouslySetInnerHTML) return el;
    if (el.type === "img" || el.type === "svg" || el.type === "br" || el.type === "hr") return el;

    const rawChildren = React.Children.toArray(el.props.children);
    if (rawChildren.length === 0) {
      // Sem filhos = elemento decorativo (círculo de fundo, barra, etc.) — preserva
      return el;
    }

    const newChildren = [];
    for (const child of rawChildren) {
      const stripped = stripEmpty(child);
      if (stripped === null || stripped === "") continue;
      newChildren.push(stripped);
    }

    // Tinha filhos mas todos eram vazios → elemento provavelmente é wrapper de texto vazio. Remove.
    if (newChildren.length === 0) return null;

    return React.cloneElement(el, el.props, ...newChildren);
  }

  for (const t of window.LIROU_TEMPLATES) {
    const orig = t.render;
    const skipColorVars = t.skipColorPatch || (t.group || "").startsWith("Adesivos");
    t.render = function (d) {
      let wrapped = orig(d);
      // Sempre passa por stripEmpty (mesmo nos adesivos)
      try {
        wrapped = stripEmpty(wrapped);
        if (!wrapped) return null;
      } catch (e) {
        // se algo der errado, segue com o output original
      }
      if (skipColorVars) return wrapped;
      try {
        const style = (wrapped && wrapped.props && wrapped.props.style) || {};
        const merged = {
          ...style,
          ["--lirou-btn"]: d.btn || "#674689",
          ["--lirou-btn-text"]: d.btnText || "#ffffff",
          ["--lirou-glyph"]: d.glyph || d.accent || "#674689",
          ["--lirou-fg"]: d.fg || "#1b1b1a",
          ["--lirou-bg"]: d.bg || "#eadcbe",
          ["--lirou-accent"]: d.accent || "#674689",
        };
        return React.cloneElement(wrapped, { style: merged });
      } catch {
        return wrapped;
      }
    };
  }
})();
