// Auto-linkify bare http(s) URLs in plain (non-markdown) row text —
// Preact-node port of @hive/shared/terminal.js's `linkify` (text-node
// output there, JSX fragment here). Same regex + trailing-punctuation
// strip; deliberately text-only, never innerHTML, so untrusted row text
// (matrix-relayed bodies, tool args) can't inject markup this way.
import type { JSX } from 'preact';

const LINKIFY_URL_RE = /https?:\/\/[^\s<>"']+/g;

export function linkifyToNodes(text: string | null | undefined): (string | JSX.Element)[] {
  const str = text == null ? '' : String(text);
  if (str.indexOf('://') === -1) return [str];
  const out: (string | JSX.Element)[] = [];
  let last = 0;
  let m: RegExpExecArray | null;
  let key = 0;
  LINKIFY_URL_RE.lastIndex = 0;
  while ((m = LINKIFY_URL_RE.exec(str)) !== null) {
    let url = m[0];
    const trail = url.match(/[.,;:!?)\]}'"]+$/);
    const tail = trail ? trail[0] : '';
    if (tail) url = url.slice(0, -tail.length);
    if (m.index > last) out.push(str.slice(last, m.index));
    if (!url.slice(url.indexOf('://') + 3)) {
      // Nothing past the scheme — not a real URL, emit verbatim.
      out.push(m[0]);
    } else {
      out.push(
        <a key={key++} href={url} target="_blank" rel="noopener noreferrer">
          {url}
        </a>,
      );
      if (tail) out.push(tail);
    }
    last = m.index + m[0].length;
  }
  if (last < str.length) out.push(str.slice(last));
  return out;
}
