export type CodeSegment =
  | { kind: 'text'; text: string }
  | { kind: 'inline'; text: string }
  | { kind: 'block'; text: string; lang: string | null };

const FENCE = /```([^\s`]*)[^\S\n]*\n?([\s\S]*?)\n?```/g;
const INLINE = /`([^`\n]+)`/g;

function splitInline(text: string, out: CodeSegment[]): void {
  let last = 0;
  for (const m of text.matchAll(INLINE)) {
    if (m.index > last) out.push({ kind: 'text', text: text.slice(last, m.index) });
    out.push({ kind: 'inline', text: m[1] });
    last = m.index + m[0].length;
  }
  if (last < text.length) out.push({ kind: 'text', text: text.slice(last) });
}

export function parseCode(text: string): CodeSegment[] {
  const out: CodeSegment[] = [];
  if (!text.includes('`')) {
    if (text) out.push({ kind: 'text', text });
    return out;
  }
  let last = 0;
  for (const m of text.matchAll(FENCE)) {
    splitInline(text.slice(last, m.index), out);
    out.push({ kind: 'block', text: m[2], lang: m[1] || null });
    last = m.index + m[0].length;
    if (text[last] === '\n') last += 1;
  }
  splitInline(text.slice(last), out);
  return out;
}

export function hasCode(segments: CodeSegment[]): boolean {
  return segments.some((s) => s.kind !== 'text');
}
