"use client";

/**
 * Lightweight markdown renderer for component technical docs.
 * Robust tables (GFM), fenced code, lists, headings.
 */

import { useMemo } from "react";

type Block =
  | { kind: "h"; level: number; text: string }
  | { kind: "p"; text: string }
  | { kind: "code"; text: string }
  | { kind: "ul"; items: string[] }
  | { kind: "ol"; items: string[] }
  | { kind: "table"; headers: string[]; rows: string[][] }
  | { kind: "hr" }
  | { kind: "blockquote"; text: string };

function isSepLine(line: string): boolean {
  const t = line.trim();
  if (!t.includes("-") && !t.includes(":")) return false;
  // GFM separator: | --- | :---: | ---: |
  return /^\|?[\s|:\-]+$/.test(t) && /-+/.test(t);
}

function splitCells(row: string): string[] {
  let r = row.trim();
  if (r.startsWith("|")) r = r.slice(1);
  if (r.endsWith("|")) r = r.slice(0, -1);
  return r.split("|").map((c) => c.trim());
}

function parseBlocks(md: string): Block[] {
  const lines = md.replace(/\r\n/g, "\n").replace(/\r/g, "\n").split("\n");
  const blocks: Block[] = [];
  let i = 0;

  while (i < lines.length) {
    const line = lines[i];

    if (line.startsWith("```")) {
      const body: string[] = [];
      i += 1;
      while (i < lines.length && !lines[i].startsWith("```")) {
        body.push(lines[i]);
        i += 1;
      }
      if (i < lines.length) i += 1;
      blocks.push({ kind: "code", text: body.join("\n") });
      continue;
    }

    const hm = /^(#{1,4})\s+(.+)$/.exec(line);
    if (hm) {
      blocks.push({ kind: "h", level: hm[1].length, text: hm[2].trim() });
      i += 1;
      continue;
    }

    if (/^---+$/.test(line.trim()) || /^\*\*\*+$/.test(line.trim())) {
      blocks.push({ kind: "hr" });
      i += 1;
      continue;
    }

    if (line.startsWith(">")) {
      const parts: string[] = [];
      while (i < lines.length && lines[i].startsWith(">")) {
        parts.push(lines[i].replace(/^>\s?/, ""));
        i += 1;
      }
      blocks.push({ kind: "blockquote", text: parts.join(" ") });
      continue;
    }

    // Table: header line with | and next line is separator
    if (line.includes("|") && i + 1 < lines.length && isSepLine(lines[i + 1])) {
      const headers = splitCells(line);
      i += 2;
      const rows: string[][] = [];
      while (i < lines.length && lines[i].includes("|") && lines[i].trim() !== "" && !isSepLine(lines[i])) {
        const cells = splitCells(lines[i]);
        // pad / trim to header width
        while (cells.length < headers.length) cells.push("");
        rows.push(cells.slice(0, headers.length));
        i += 1;
      }
      blocks.push({ kind: "table", headers, rows });
      continue;
    }

    if (/^\s*[-*]\s+/.test(line)) {
      const items: string[] = [];
      while (i < lines.length && /^\s*[-*]\s+/.test(lines[i])) {
        items.push(lines[i].replace(/^\s*[-*]\s+/, ""));
        i += 1;
      }
      blocks.push({ kind: "ul", items });
      continue;
    }

    if (/^\s*\d+\.\s+/.test(line)) {
      const items: string[] = [];
      while (i < lines.length && /^\s*\d+\.\s+/.test(lines[i])) {
        items.push(lines[i].replace(/^\s*\d+\.\s+/, ""));
        i += 1;
      }
      blocks.push({ kind: "ol", items });
      continue;
    }

    if (line.trim() === "") {
      i += 1;
      continue;
    }

    // paragraph — stop before tables/lists/headings/code
    const parts: string[] = [];
    while (i < lines.length) {
      const L = lines[i];
      if (L.trim() === "") break;
      if (L.startsWith("#") || L.startsWith("```") || L.startsWith(">")) break;
      if (/^\s*[-*]\s+/.test(L) || /^\s*\d+\.\s+/.test(L)) break;
      if (L.includes("|") && i + 1 < lines.length && isSepLine(lines[i + 1])) break;
      if (isSepLine(L)) break;
      parts.push(L.trim());
      i += 1;
    }
    if (parts.length) blocks.push({ kind: "p", text: parts.join(" ") });
  }

  return blocks;
}

function Inline({ text }: { text: string }) {
  const parts = text.split(/(`[^`]+`|\*\*[^*]+\*\*|\[[^\]]+\]\([^)]+\))/g);
  return (
    <>
      {parts.map((part, idx) => {
        if (!part) return null;
        if (part.startsWith("`") && part.endsWith("`") && part.length >= 2) {
          return (
            <code key={idx} className="doc-code-inline">
              {part.slice(1, -1)}
            </code>
          );
        }
        if (part.startsWith("**") && part.endsWith("**") && part.length >= 4) {
          return <strong key={idx}>{part.slice(2, -2)}</strong>;
        }
        const lm = /^\[([^\]]+)\]\(([^)]+)\)$/.exec(part);
        if (lm) {
          return (
            <a key={idx} href={lm[2]} className="doc-link" target="_blank" rel="noreferrer">
              {lm[1]}
            </a>
          );
        }
        return <span key={idx}>{part}</span>;
      })}
    </>
  );
}

export default function MarkdownDoc({ source }: { source: string }) {
  const blocks = useMemo(() => parseBlocks(source), [source]);

  return (
    <div className="doc-md">
      {blocks.map((b, i) => {
        switch (b.kind) {
          case "h":
            if (b.level <= 1)
              return (
                <h1 key={i} className="doc-h1">
                  <Inline text={b.text} />
                </h1>
              );
            if (b.level === 2)
              return (
                <h2 key={i} className="doc-h2">
                  <Inline text={b.text} />
                </h2>
              );
            if (b.level === 3)
              return (
                <h3 key={i} className="doc-h3">
                  <Inline text={b.text} />
                </h3>
              );
            return (
              <h4 key={i} className="doc-h4">
                <Inline text={b.text} />
              </h4>
            );
          case "p":
            return (
              <p key={i} className="doc-p">
                <Inline text={b.text} />
              </p>
            );
          case "code":
            return (
              <pre key={i} className="doc-pre">
                <code>{b.text}</code>
              </pre>
            );
          case "ul":
            return (
              <ul key={i} className="doc-ul">
                {b.items.map((it, j) => (
                  <li key={j}>
                    <Inline text={it} />
                  </li>
                ))}
              </ul>
            );
          case "ol":
            return (
              <ol key={i} className="doc-ol">
                {b.items.map((it, j) => (
                  <li key={j}>
                    <Inline text={it} />
                  </li>
                ))}
              </ol>
            );
          case "table":
            return (
              <div key={i} className="doc-table-wrap">
                <table className="doc-table">
                  <thead>
                    <tr>
                      {b.headers.map((h, j) => (
                        <th key={j}>
                          <Inline text={h} />
                        </th>
                      ))}
                    </tr>
                  </thead>
                  <tbody>
                    {b.rows.map((row, ri) => (
                      <tr key={ri}>
                        {row.map((cell, ci) => (
                          <td key={ci}>
                            <Inline text={cell} />
                          </td>
                        ))}
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            );
          case "hr":
            return <hr key={i} className="doc-hr" />;
          case "blockquote":
            return (
              <blockquote key={i} className="doc-quote">
                <Inline text={b.text} />
              </blockquote>
            );
          default:
            return null;
        }
      })}
      <style jsx>{`
        :global(.doc-md) {
          font-size: 11px;
          line-height: 1.45;
          color: var(--ink-dim);
        }
        :global(.doc-h1) {
          font-size: 13px;
          font-weight: 700;
          color: var(--ink);
          margin: 0.4em 0 0.3em;
        }
        :global(.doc-h2) {
          font-size: 12px;
          font-weight: 700;
          color: var(--ink);
          margin: 0.75em 0 0.3em;
          padding-bottom: 0.15em;
          border-bottom: 1px solid var(--line);
        }
        :global(.doc-h3) {
          font-size: 11px;
          font-weight: 650;
          color: var(--ink);
          margin: 0.55em 0 0.2em;
        }
        :global(.doc-h4) {
          font-size: 11px;
          font-weight: 600;
          margin: 0.45em 0 0.15em;
        }
        :global(.doc-p) {
          margin: 0.3em 0;
        }
        :global(.doc-pre) {
          margin: 0.35em 0;
          padding: 8px 10px;
          border-radius: 4px;
          border: 1px solid var(--line);
          background: #0f172a;
          color: #e2e8f0;
          font-family: var(--font-mono), ui-monospace, monospace;
          font-size: 10px;
          line-height: 1.4;
          overflow-x: auto;
          white-space: pre-wrap;
          word-break: break-word;
        }
        :global(.doc-code-inline) {
          font-family: var(--font-mono), ui-monospace, monospace;
          font-size: 10px;
          background: var(--chrome-2);
          border: 1px solid var(--line);
          border-radius: 3px;
          padding: 0 3px;
          color: var(--ink);
        }
        :global(.doc-ul),
        :global(.doc-ol) {
          margin: 0.3em 0;
          padding-left: 1.2em;
        }
        :global(.doc-table-wrap) {
          overflow-x: auto;
          margin: 0.4em 0;
          max-width: 100%;
        }
        :global(.doc-table) {
          width: 100%;
          border-collapse: collapse;
          font-size: 10px;
          table-layout: auto;
        }
        :global(.doc-table th),
        :global(.doc-table td) {
          border: 1px solid var(--line);
          padding: 4px 6px;
          text-align: left;
          vertical-align: top;
          word-break: break-word;
        }
        :global(.doc-table th) {
          background: var(--chrome-2);
          font-weight: 600;
          color: var(--ink);
          white-space: nowrap;
        }
        :global(.doc-hr) {
          border: none;
          border-top: 1px solid var(--line);
          margin: 0.6em 0;
        }
        :global(.doc-quote) {
          margin: 0.35em 0;
          padding: 6px 8px;
          border-left: 3px solid var(--accent);
          background: var(--chrome-2);
        }
        :global(.doc-link) {
          color: var(--accent);
          text-decoration: underline;
        }
      `}</style>
    </div>
  );
}
