/* ==========================================================================
   JSON TREE VIEWER COMPONENT
   Foldable nodes, syntax highlighting, copy to clipboard, search
   ========================================================================== */

const JSONViewer = {
  render(containerId, data) {
    const container = document.getElementById(containerId);
    if (!container) return;

    container.innerHTML = '';
    const wrapper = document.createElement('div');
    wrapper.className = 'json-viewer-container';

    // Toolbar superior
    const toolbar = document.createElement('div');
    toolbar.className = 'json-viewer-toolbar';
    toolbar.innerHTML = `
      <div class="json-viewer-title">
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><polyline points="16 18 22 12 16 6"></polyline><polyline points="8 6 2 12 8 18"></polyline></svg>
        <span>Payload Bruto (JSON)</span>
      </div>
      <div class="json-viewer-actions">
        <button class="btn btn-secondary btn-sm" id="btn-json-expand-all" title="Expandir Todos">
          Expandir Tudo
        </button>
        <button class="btn btn-secondary btn-sm" id="btn-json-collapse-all" title="Recolher Todos">
          Recolher
        </button>
        <button class="btn btn-primary btn-sm" id="btn-json-copy" title="Copiar JSON Formatado">
          <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>
          Copiar
        </button>
      </div>
    `;

    const treeBody = document.createElement('div');
    treeBody.className = 'json-tree-body';

    const rootNode = this.createNode('', data, true);
    treeBody.appendChild(rootNode);

    wrapper.appendChild(toolbar);
    wrapper.appendChild(treeBody);
    container.appendChild(wrapper);

    // Bind Toolbar Actions
    const btnExpand = wrapper.querySelector('#btn-json-expand-all');
    if (btnExpand) {
      btnExpand.addEventListener('click', () => {
        wrapper.querySelectorAll('.json-node').forEach((node) => {
          node.classList.remove('collapsed-content');
          const toggle = node.querySelector(':scope > .json-toggle');
          if (toggle) toggle.classList.remove('collapsed');
        });
      });
    }

    const btnCollapse = wrapper.querySelector('#btn-json-collapse-all');
    if (btnCollapse) {
      btnCollapse.addEventListener('click', () => {
        wrapper.querySelectorAll('.json-node').forEach((node) => {
          // Deixar raiz aberta
          if (node !== rootNode) {
            node.classList.add('collapsed-content');
            const toggle = node.querySelector(':scope > .json-toggle');
            if (toggle) toggle.classList.add('collapsed');
          }
        });
      });
    }

    const btnCopy = wrapper.querySelector('#btn-json-copy');
    if (btnCopy) {
      btnCopy.addEventListener('click', () => {
        const jsonStr = JSON.stringify(data, null, 2);
        navigator.clipboard.writeText(jsonStr).then(() => {
          showToast('JSON copiado para a área de transferência!', 'success');
        }).catch(() => {
          showToast('Erro ao copiar JSON.', 'error');
        });
      });
    }
  },

  createNode(key, value, isRoot = false) {
    const node = document.createElement('div');
    node.className = 'json-node';

    const type = this.getType(value);

    if (type === 'object' || type === 'array') {
      const isArray = type === 'array';
      const openBracket = isArray ? '[' : '{';
      const closeBracket = isArray ? ']' : '}';
      const keys = Object.keys(value || {});
      const count = keys.length;

      const toggle = document.createElement('span');
      toggle.className = 'json-toggle';
      toggle.innerHTML = '▼';

      toggle.addEventListener('click', (e) => {
        e.stopPropagation();
        node.classList.toggle('collapsed-content');
        toggle.classList.toggle('collapsed');
      });

      node.appendChild(toggle);

      const header = document.createElement('span');
      if (key !== '') {
        header.innerHTML = `<span class="json-key">"${key}"</span><span class="json-colon">: </span>`;
      }
      header.innerHTML += `<span class="json-bracket">${openBracket}</span>`;
      header.innerHTML += `<span class="json-ellipsis"> ... </span>`;
      header.innerHTML += `<span class="json-size-hint">// ${count} ${isArray ? 'itens' : 'chaves'}</span>`;

      node.appendChild(header);

      const childrenContainer = document.createElement('div');
      childrenContainer.className = 'json-children';

      keys.forEach((childKey) => {
        const childNode = this.createNode(isArray ? '' : childKey, value[childKey]);
        childrenContainer.appendChild(childNode);
      });

      node.appendChild(childrenContainer);

      const footer = document.createElement('div');
      footer.className = 'json-footer';
      footer.innerHTML = `<span class="json-bracket">${closeBracket}</span>`;
      node.appendChild(footer);

    } else {
      // Primitive Value
      const line = document.createElement('span');
      if (key !== '') {
        line.innerHTML = `<span class="json-key">"${key}"</span><span class="json-colon">: </span>`;
      }

      if (type === 'string') {
        line.innerHTML += `<span class="json-string">"${this.escapeHtml(value)}"</span>`;
      } else if (type === 'number') {
        line.innerHTML += `<span class="json-number">${value}</span>`;
      } else if (type === 'boolean') {
        line.innerHTML += `<span class="json-boolean">${value}</span>`;
      } else if (type === 'null') {
        line.innerHTML += `<span class="json-null">null</span>`;
      } else {
        line.innerHTML += `<span class="json-string">"${value}"</span>`;
      }

      node.appendChild(line);
    }

    return node;
  },

  getType(val) {
    if (val === null) return 'null';
    if (Array.isArray(val)) return 'array';
    return typeof val;
  },

  escapeHtml(str) {
    return String(str)
      .replace(/&/g, '&amp;')
      .replace(/</g, '&lt;')
      .replace(/>/g, '&gt;')
      .replace(/"/g, '&quot;');
  }
};
