// MarkdownView — pure renderer over lib/markdown.js block trees. Builds React
// elements directly (never HTML strings), so agent/user-echoed content cannot
// inject markup. Used by the chat brief card and the create-page brief pane.
//
// Props:
//   markdown — the raw markdown string (null/empty renders nothing)

const MD_HEADING_CLS = {
  1: 'text-lg font-black text-neutral-900 mt-4 mb-1.5',
  2: 'text-base font-bold text-neutral-900 mt-4 mb-1.5',
  3: 'text-sm font-bold text-neutral-800 mt-3 mb-1',
  4: 'text-sm font-semibold text-neutral-800 mt-3 mb-1',
  5: 'text-xs font-bold uppercase tracking-widest text-neutral-500 mt-3 mb-1',
  6: 'text-xs font-semibold uppercase tracking-widest text-neutral-500 mt-3 mb-1',
};

const MdSpans = ({ spans }) => (spans || []).map((s, i) => {
  if (s.type === 'bold') return <strong key={i} className="font-semibold text-neutral-900">{s.text}</strong>;
  if (s.type === 'em') return <em key={i}>{s.text}</em>;
  if (s.type === 'code') return <code key={i} className="font-mono text-[0.85em] bg-neutral-100 border border-neutral-200 rounded px-1 py-px">{s.text}</code>;
  if (s.type === 'link') return <a key={i} href={s.href} target="_blank" rel="noopener noreferrer" className="text-indigo-600 underline decoration-indigo-300 hover:decoration-indigo-600">{s.text}</a>;
  return <React.Fragment key={i}>{s.text}</React.Fragment>;
});

const MarkdownView = ({ markdown }) => {
  if (!markdown) return null;
  const blocks = window.Markdown.parseMarkdown(markdown);
  return (
    <div className="text-sm text-neutral-800 leading-relaxed [&>*:first-child]:mt-0">
      {blocks.map((b, i) => {
        switch (b.type) {
          case 'heading':
            return React.createElement(`h${b.level}`, { key: i, className: MD_HEADING_CLS[b.level] }, <MdSpans spans={b.spans} />);
          case 'list':
            return b.ordered ? (
              <ol key={i} className="list-decimal list-outside pl-5 my-1.5 space-y-0.5">
                {b.items.map((item, j) => <li key={j}><MdSpans spans={item} /></li>)}
              </ol>
            ) : (
              <ul key={i} className="list-disc list-outside pl-5 my-1.5 space-y-0.5">
                {b.items.map((item, j) => <li key={j}><MdSpans spans={item} /></li>)}
              </ul>
            );
          case 'tasklist':
            // Acceptance criteria. Read-only: these reflect the task's written
            // criteria, they are not a control surface — the line decides done-ness.
            return (
              <ul key={i} className="list-none pl-0 my-1.5 space-y-1">
                {b.items.map((item, j) => (
                  <li key={j} className="flex items-start gap-2">
                    {item.checked === null ? (
                      <span className="mt-1 w-3.5 shrink-0" />
                    ) : (
                      <input
                        type="checkbox"
                        checked={item.checked}
                        readOnly
                        disabled
                        aria-label={item.checked ? 'met' : 'not met'}
                        className="mt-1 w-3.5 h-3.5 shrink-0 accent-emerald-600"
                      />
                    )}
                    <span className={item.checked ? 'text-neutral-400 line-through' : ''}><MdSpans spans={item.spans} /></span>
                  </li>
                ))}
              </ul>
            );
          case 'code':
            return <pre key={i} className="font-mono text-xs bg-neutral-900 text-neutral-100 rounded-lg p-3 my-2 overflow-x-auto">{b.text}</pre>;
          case 'hr':
            return <div key={i} className="h-px bg-neutral-200 my-3" />;
          default:
            return <p key={i} className="my-1.5"><MdSpans spans={b.spans} /></p>;
        }
      })}
    </div>
  );
};

if (typeof window !== 'undefined') {
  window.MarkdownView = MarkdownView;
}
