import { Fragment, isValidElement, type ReactNode } from 'react';

const TOKEN_RE = /(\*\*[^*\n][\s\S]*?[^*\n]\*\*|`[^`\n]+`|\[[^\]\n]+\]\(https?:\/\/[^)\s]+\))/g;

function renderToken(token: string, key: string): ReactNode {
  if (token.startsWith('**') && token.endsWith('**')) {
    return (
      <strong key={key} className="font-semibold text-foreground">
        {token.slice(2, -2)}
      </strong>
    );
  }

  if (token.startsWith('`') && token.endsWith('`')) {
    return (
      <code key={key} className="rounded bg-muted px-1 py-0.5 font-mono text-[0.92em] text-foreground">
        {token.slice(1, -1)}
      </code>
    );
  }

  const link = token.match(/^\[([^\]\n]+)\]\((https?:\/\/[^)\s]+)\)$/);
  if (link) {
    return (
      <a
        key={key}
        href={link[2]}
        target="_blank"
        rel="noopener noreferrer"
        className="font-medium text-primary underline-offset-4 hover:underline"
      >
        {link[1]}
      </a>
    );
  }

  return token;
}

export function renderInlineMarkdown(text: string | null | undefined): ReactNode {
  if (!text) return null;

  const parts: ReactNode[] = [];
  let lastIndex = 0;

  for (const match of text.matchAll(TOKEN_RE)) {
    const mi = match.index ?? 0;
    if (mi > lastIndex) {
      parts.push(text.slice(lastIndex, mi));
    }
    parts.push(renderToken(match[0], `md-${mi}`));
    lastIndex = mi + match[0].length;
  }

  if (lastIndex < text.length) {
    parts.push(text.slice(lastIndex));
  }

  return parts.map((part, index) => (
    <Fragment key={isValidElement(part) ? (part.key ?? index) : `text-${index}`}>
      {part}
    </Fragment>
  ));
}

export function MarkdownText({ text }: { text?: string | null }): ReactNode {
  return renderInlineMarkdown(text);
}
