import React from 'react';

/**
 * Renders the assistant's lightweight markdown as clean text: headings,
 * bullet/numbered lists, **bold** and *italic* — without showing the symbols.
 */
export function ChatText({ text }: { text: string }) {
  const blocks: React.ReactNode[] = [];
  let list: { ordered: boolean; items: string[] } | null = null;

  const flushList = () => {
    if (!list) return;
    const { ordered, items } = list;
    blocks.push(
      <ul key={blocks.length} className="space-y-1.5">
        {items.map((item, i) => (
          <li key={i} className="flex gap-2.5">
            {ordered ? (
              <span className="min-w-4 shrink-0 font-semibold text-ink-soft tabular-nums">{i + 1}.</span>
            ) : (
              <span aria-hidden className="mt-[0.6em] size-1.5 shrink-0 rounded-full bg-accent" />
            )}
            <span>{renderInline(item)}</span>
          </li>
        ))}
      </ul>,
    );
    list = null;
  };

  for (const raw of text.replace(/\r\n/g, '\n').split('\n')) {
    const line = raw.trim();

    if (!line || /^(-{3,}|\*{3,}|_{3,})$/.test(line)) {
      flushList();
      continue;
    }

    const heading = line.match(/^#{1,6}\s+(.*)$/);
    if (heading) {
      flushList();
      blocks.push(
        <p key={blocks.length} className="pt-1 font-semibold text-ink">
          {renderInline(heading[1])}
        </p>,
      );
      continue;
    }

    const bullet = line.match(/^[-*•]\s+(.*)$/);
    const numbered = line.match(/^\d+[.)]\s+(.*)$/);
    if (bullet || numbered) {
      const ordered = Boolean(numbered);
      if (list && list.ordered !== ordered) flushList();
      list ??= { ordered, items: [] };
      list.items.push((bullet ?? numbered)![1]);
      continue;
    }

    flushList();
    blocks.push(<p key={blocks.length}>{renderInline(line.replace(/^>\s?/, ''))}</p>);
  }
  flushList();

  return <div className="space-y-3">{blocks}</div>;
}

function renderInline(text: string): React.ReactNode[] {
  // Split on **bold**, __bold__, *italic*, _italic_ and `code`, keeping the markers.
  return text
    .split(/(\*\*[^*]+\*\*|__[^_]+__|\*[^*\s][^*]*\*|_[^_\s][^_]*_|`[^`]+`)/g)
    .filter(Boolean)
    .map((part, i) => {
      if (/^(\*\*|__).+\1$/.test(part)) {
        return (
          <strong key={i} className="font-semibold text-ink">
            {part.slice(2, -2)}
          </strong>
        );
      }
      if (/^([*_]).+\1$/.test(part)) return <em key={i}>{part.slice(1, -1)}</em>;
      if (/^`.+`$/.test(part)) return <span key={i}>{part.slice(1, -1)}</span>;
      // Stray markers the model left unbalanced.
      return part.replace(/\*\*|__/g, '');
    });
}
