// XML to JSON — parse XML via DOMParser, emit a JSON tree.

window.TOOL_HANDLERS['xml-to-json'] = function XmlToJsonTool() {
  const [xml, setXml] = React.useState('<note>\n  <to>Dev</to>\n  <from>MiniMagics</from>\n  <msg>Paste XML here</msg>\n</note>');
  const [error, setError] = React.useState('');

  const json = React.useMemo(() => {
    try {
      const doc = new DOMParser().parseFromString(xml, 'text/xml');
      const parserError = doc.querySelector('parsererror');
      if (parserError) throw new Error(parserError.textContent);
      const walk = (node) => {
        if (node.nodeType === 3) return node.nodeValue.trim() || null;
        if (node.nodeType !== 1) return null;
        const obj = {};
        for (const a of node.attributes || []) obj['@' + a.name] = a.value;
        const kids = [...node.childNodes].map(walk).filter(v => v !== null);
        if (kids.length === 0 && Object.keys(obj).length === 0) return '';
        if (kids.every(k => typeof k === 'string')) {
          const text = kids.join('');
          if (Object.keys(obj).length === 0) return text;
          obj['#text'] = text;
          return obj;
        }
        for (const k of kids) {
          if (typeof k !== 'object') continue;
          for (const [key, val] of Object.entries(k)) {
            if (obj[key] !== undefined) {
              if (!Array.isArray(obj[key])) obj[key] = [obj[key]];
              obj[key].push(val);
            } else obj[key] = val;
          }
        }
        return obj;
      };
      const root = doc.documentElement;
      setError('');
      return JSON.stringify({ [root.tagName]: walk(root) }, null, 2);
    } catch (e) {
      setError(e.message);
      return '';
    }
  }, [xml]);

  return (
    <div className="mini-tool">
      <div className="mini-grid">
        <div className="mini-left">
          <label className="mini-label">XML input</label>
          <textarea className="mini-input mini-textarea" style={{ minHeight: 260, fontFamily: 'ui-monospace, monospace', fontSize: 12 }}
            value={xml} onChange={(e) => setXml(e.target.value)} />
        </div>
        <div className="mini-right">
          <label className="mini-label">JSON output</label>
          <textarea className="mini-input mini-textarea" readOnly style={{ minHeight: 260, fontFamily: 'ui-monospace, monospace', fontSize: 12 }}
            value={error || json} />
          <button className="btn btn-primary" style={{ marginTop: 10, width: '100%' }}
                  onClick={() => navigator.clipboard.writeText(json)} disabled={!!error}>
            <window.Icon name="doc" size={16} /> Copy JSON
          </button>
        </div>
      </div>
    </div>
  );
};
