'use client'

// Minimal, SAFE markdown -> React renderer. No dangerouslySetInnerHTML, no dependency.
// Covers the subset LLMs emit: headings, bold, italic, inline code, fenced code, ul/ol, links.
// Plus deliberate [n] citation markers (mapped via `citations`, NOT parsed for structure).

export interface CiteHandler {
  count: number
  onSelect: (n: number) => void
}

const INLINE_RE =
  /(`[^`]+`|\*\*[^*]+\*\*|\*[^*\s][^*]*\*|_[^_]+_|\[[^\]]+\]\([^)]+\)|\[\d+\])/g

function renderInline(text: string, kp: string, cite?: CiteHandler): React.ReactNode[] {
  const nodes: React.ReactNode[] = []
  let last = 0
  let idx = 0
  INLINE_RE.lastIndex = 0
  let m: RegExpExecArray | null
  while ((m = INLINE_RE.exec(text)) !== null) {
    if (m.index > last) nodes.push(text.slice(last, m.index))
    const tok = m[0]
    const key = `${kp}-${idx++}`
    if (tok.startsWith('`')) {
      nodes.push(
        <code key={key} className="rounded bg-gray-100 px-1 py-0.5 font-mono text-[0.85em]">
          {tok.slice(1, -1)}
        </code>,
      )
    } else if (tok.startsWith('**')) {
      nodes.push(
        <strong key={key} className="font-semibold text-gray-900">
          {tok.slice(2, -2)}
        </strong>,
      )
    } else if (tok.startsWith('*') || tok.startsWith('_')) {
      nodes.push(<em key={key}>{tok.slice(1, -1)}</em>)
    } else if (/^\[\d+\]$/.test(tok)) {
      const n = parseInt(tok.slice(1, -1), 10)
      if (cite && n >= 1 && n <= cite.count) {
        nodes.push(
          <button
            key={key}
            type="button"
            onClick={() => cite.onSelect(n)}
            className="mx-0.5 align-super text-[10px] font-semibold text-indigo-600 hover:underline"
            title={`Beleg ${n} anzeigen`}
          >
            [{n}]
          </button>,
        )
      } else {
        nodes.push(tok)
      }
    } else {
      const mm = /^\[([^\]]+)\]\(([^)]+)\)$/.exec(tok)
      if (mm && /^https?:\/\//i.test(mm[2])) {
        nodes.push(
          <a
            key={key}
            href={mm[2]}
            target="_blank"
            rel="noopener noreferrer"
            className="text-indigo-600 underline hover:text-indigo-800"
          >
            {mm[1]}
          </a>,
        )
      } else {
        nodes.push(mm ? mm[1] : tok)
      }
    }
    last = m.index + tok.length
  }
  if (last < text.length) nodes.push(text.slice(last))
  return nodes
}

function Heading({ level, kp, text, cite }: { level: number; kp: string; text: string; cite?: CiteHandler }) {
  const children = renderInline(text, kp, cite)
  if (level <= 1) return <h3 className="mb-1 mt-3 text-base font-bold text-gray-900">{children}</h3>
  if (level === 2) return <h4 className="mb-1 mt-3 text-sm font-bold text-gray-900">{children}</h4>
  return <h5 className="mb-1 mt-2 text-sm font-semibold text-gray-800">{children}</h5>
}

const UL_RE = /^\s*[-*]\s+/
const OL_RE = /^\s*\d+\.\s+/
const H_RE = /^(#{1,6})\s+(.*)$/

export function Markdown({ content, citations }: { content: string; citations?: CiteHandler }) {
  const lines = (content || '').replace(/\r\n/g, '\n').split('\n')
  const blocks: React.ReactNode[] = []
  let i = 0
  while (i < lines.length) {
    const line = lines[i]
    const key = `b${blocks.length}`

    if (line.trim().startsWith('```')) {
      const buf: string[] = []
      i++
      while (i < lines.length && !lines[i].trim().startsWith('```')) {
        buf.push(lines[i])
        i++
      }
      i++
      blocks.push(
        <pre
          key={key}
          className="my-2 overflow-x-auto rounded bg-gray-900 p-3 font-mono text-xs text-gray-100"
        >
          <code>{buf.join('\n')}</code>
        </pre>,
      )
      continue
    }
    if (line.trim() === '') {
      i++
      continue
    }
    const h = H_RE.exec(line)
    if (h) {
      blocks.push(<Heading key={key} kp={key} level={h[1].length} text={h[2]} cite={citations} />)
      i++
      continue
    }
    if (UL_RE.test(line)) {
      const items: string[] = []
      while (i < lines.length && UL_RE.test(lines[i])) {
        items.push(lines[i].replace(UL_RE, ''))
        i++
      }
      blocks.push(
        <ul key={key} className="my-1.5 ml-4 list-disc space-y-1 text-gray-700">
          {items.map((it, k) => (
            <li key={k}>{renderInline(it, `${key}-${k}`, citations)}</li>
          ))}
        </ul>,
      )
      continue
    }
    if (OL_RE.test(line)) {
      const items: string[] = []
      while (i < lines.length && OL_RE.test(lines[i])) {
        items.push(lines[i].replace(OL_RE, ''))
        i++
      }
      blocks.push(
        <ol key={key} className="my-1.5 ml-5 list-decimal space-y-1 text-gray-700">
          {items.map((it, k) => (
            <li key={k}>{renderInline(it, `${key}-${k}`, citations)}</li>
          ))}
        </ol>,
      )
      continue
    }
    const para: string[] = []
    while (
      i < lines.length &&
      lines[i].trim() !== '' &&
      !H_RE.test(lines[i]) &&
      !UL_RE.test(lines[i]) &&
      !OL_RE.test(lines[i]) &&
      !lines[i].trim().startsWith('```')
    ) {
      para.push(lines[i])
      i++
    }
    blocks.push(
      <p key={key} className="my-1.5 leading-relaxed text-gray-700">
        {renderInline(para.join(' '), key, citations)}
      </p>,
    )
  }
  return <div className="advisor-markdown text-sm">{blocks}</div>
}
