import { Fragment, jsx, jsxs } from "react/jsx-runtime";
import { memo, useMemo } from "react";
import { Text, Box, useStdout } from "ink";
import chalk from "chalk";
import wrapAnsi from "wrap-ansi";
import stringWidth from "string-width";
import { highlight, supportsLanguage } from "cli-highlight";
function parseInlineMarkdown(text) {
  if (!/[*_~`\[<]|https?:\/\//.test(text)) {
    return [{ type: "text", content: text }];
  }
  const segments = [];
  let lastIndex = 0;
  const inlineRegex = /(\*\*[^*]+\*\*|__[^_]+__|`[^`]+`|\*[^*]+\*|_[^_]+_|~~[^~]+~~|\[[^\]]+\]\([^)]+\)|https?:\/\/[^\s<]+)/g;
  let match;
  while ((match = inlineRegex.exec(text)) !== null) {
    if (match.index > lastIndex) {
      segments.push({ type: "text", content: text.slice(lastIndex, match.index) });
    }
    const fullMatch = match[0];
    if (fullMatch.startsWith("**") && fullMatch.endsWith("**") && fullMatch.length > 4) {
      segments.push({ type: "bold", content: fullMatch.slice(2, -2) });
    } else if (fullMatch.startsWith("__") && fullMatch.endsWith("__") && fullMatch.length > 4) {
      segments.push({ type: "bold", content: fullMatch.slice(2, -2) });
    } else if (fullMatch.startsWith("`") && fullMatch.endsWith("`") && fullMatch.length > 2) {
      segments.push({ type: "code", content: fullMatch.slice(1, -1) });
    } else if (fullMatch.startsWith("~~") && fullMatch.endsWith("~~") && fullMatch.length > 4) {
      segments.push({ type: "strikethrough", content: fullMatch.slice(2, -2) });
    } else if (fullMatch.startsWith("*") && fullMatch.endsWith("*") && fullMatch.length > 2) {
      segments.push({ type: "italic", content: fullMatch.slice(1, -1) });
    } else if (fullMatch.startsWith("_") && fullMatch.endsWith("_") && fullMatch.length > 2) {
      segments.push({ type: "italic", content: fullMatch.slice(1, -1) });
    } else if (fullMatch.startsWith("[") && fullMatch.includes("](") && fullMatch.endsWith(")")) {
      const linkMatch = fullMatch.match(/\[([^\]]+)\]\(([^)]+)\)/);
      if (linkMatch && linkMatch[1] && linkMatch[2]) {
        segments.push({ type: "link", content: linkMatch[1], url: linkMatch[2] });
      } else {
        segments.push({ type: "text", content: fullMatch });
      }
    } else if (/^https?:\/\//.test(fullMatch)) {
      segments.push({ type: "url", content: fullMatch });
    } else {
      segments.push({ type: "text", content: fullMatch });
    }
    lastIndex = inlineRegex.lastIndex;
  }
  if (lastIndex < text.length) {
    segments.push({ type: "text", content: text.slice(lastIndex) });
  }
  return segments;
}
function segmentsToAnsi(segments, defaultColor) {
  const colorFn = getChalkColor(defaultColor);
  return segments.map((segment) => {
    switch (segment.type) {
      case "bold":
        return colorFn.bold(segment.content);
      case "code":
        return chalk.cyan(segment.content);
      case "italic":
        return chalk.gray(segment.content);
      case "strikethrough":
        return colorFn.strikethrough(segment.content);
      case "link":
        return colorFn(segment.content) + chalk.blue(` (${segment.url})`);
      case "url":
        return chalk.blue(segment.content);
      default:
        return colorFn(segment.content);
    }
  }).join("");
}
function getChalkColor(color) {
  switch (color) {
    case "white":
      return chalk.white;
    case "gray":
      return chalk.gray;
    case "blue":
      return chalk.blue;
    case "cyan":
      return chalk.cyan;
    case "green":
      return chalk.green;
    case "yellow":
      return chalk.rgb(255, 165, 0);
    case "orange":
      return chalk.rgb(255, 165, 0);
    case "red":
      return chalk.red;
    case "magenta":
      return chalk.green;
    default:
      return chalk.white;
  }
}
const WrappedParagraphInternal = ({
  text,
  defaultColor,
  bulletPrefix,
  isFirstParagraph = false
}) => {
  const { stdout } = useStdout();
  const terminalWidth = stdout?.columns ?? 80;
  const wrappedLines = useMemo(() => {
    const segments = parseInlineMarkdown(text);
    const ansiString = segmentsToAnsi(segments, defaultColor);
    const prefixWidth = bulletPrefix ? stringWidth(bulletPrefix) : 0;
    const availableWidth = Math.max(20, terminalWidth - prefixWidth);
    const wrapped = wrapAnsi(ansiString, availableWidth, {
      hard: false,
      // Don't break in the middle of words
      wordWrap: true,
      // Enable word wrapping
      trim: false
      // Don't trim whitespace
    });
    return wrapped.split("\n");
  }, [text, defaultColor, bulletPrefix, isFirstParagraph, terminalWidth]);
  const indentSpaces = bulletPrefix ? " ".repeat(stringWidth(bulletPrefix)) : "";
  return /* @__PURE__ */ jsx(Fragment, { children: wrappedLines.map((line, i) => {
    const isFirstLine = i === 0;
    const prefix = isFirstLine && isFirstParagraph && bulletPrefix ? bulletPrefix : indentSpaces;
    return /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Text, { children: [
      prefix,
      line
    ] }) }, i);
  }) });
};
const WrappedParagraph = memo(WrappedParagraphInternal);
const RenderInlineInternal = ({
  text,
  defaultColor = "white",
  bold: baseBold = false
}) => {
  const segments = parseInlineMarkdown(text);
  return /* @__PURE__ */ jsx(Fragment, { children: segments.map((segment, i) => {
    switch (segment.type) {
      case "bold":
        return /* @__PURE__ */ jsx(Text, { bold: true, color: defaultColor, children: segment.content }, i);
      case "code":
        return /* @__PURE__ */ jsx(Text, { bold: baseBold, color: "cyan", children: segment.content }, i);
      case "italic":
        return /* @__PURE__ */ jsx(Text, { bold: baseBold, color: "gray", children: segment.content }, i);
      case "strikethrough":
        return /* @__PURE__ */ jsx(Text, { bold: baseBold, strikethrough: true, color: defaultColor, children: segment.content }, i);
      case "link":
        return /* @__PURE__ */ jsxs(Text, { bold: baseBold, color: defaultColor, children: [
          segment.content,
          /* @__PURE__ */ jsxs(Text, { color: "blue", children: [
            " (",
            segment.url,
            ")"
          ] })
        ] }, i);
      case "url":
        return /* @__PURE__ */ jsx(Text, { bold: baseBold, color: "blue", children: segment.content }, i);
      default:
        return /* @__PURE__ */ jsx(Text, { bold: baseBold, color: defaultColor, children: segment.content }, i);
    }
  }) });
};
const RenderInline = memo(RenderInlineInternal);
const MarkdownTextInternal = ({
  children,
  color = "white",
  bulletPrefix
}) => {
  if (!children) return null;
  const defaultColor = color;
  const lines = children.split("\n");
  let isFirstContentLine = true;
  const headerRegex = /^(#{1,6})\s+(.*)$/;
  const codeFenceRegex = /^(`{3,}|~{3,})(\w*)$/;
  const ulItemRegex = /^(\s*)([-*+])\s+(.*)$/;
  const olItemRegex = /^(\s*)(\d+)\.\s+(.*)$/;
  const hrRegex = /^(\s*[-*_]\s*){3,}$/;
  const blocks = [];
  let inCodeBlock = false;
  let codeBlockLines = [];
  let codeBlockLang = "";
  let codeBlockFence = "";
  lines.forEach((line, index) => {
    const key = `line-${index}`;
    const trimmedLine = line.trim();
    if (inCodeBlock) {
      const fenceMatch = trimmedLine.match(codeFenceRegex);
      if (fenceMatch && fenceMatch[1] && codeBlockFence[0] && fenceMatch[1][0] === codeBlockFence[0] && fenceMatch[1].length >= codeBlockFence.length) {
        blocks.push(
          /* @__PURE__ */ jsx(RenderCodeBlock, { lines: codeBlockLines, language: codeBlockLang }, key)
        );
        inCodeBlock = false;
        codeBlockLines = [];
        codeBlockLang = "";
        codeBlockFence = "";
      } else {
        codeBlockLines.push(line);
      }
      return;
    }
    const codeFenceMatch = trimmedLine.match(codeFenceRegex);
    if (codeFenceMatch && codeFenceMatch[1]) {
      inCodeBlock = true;
      codeBlockFence = codeFenceMatch[1];
      codeBlockLang = codeFenceMatch[2] || "";
      return;
    }
    const headerMatch = line.match(headerRegex);
    if (headerMatch && headerMatch[1] && headerMatch[2] !== void 0) {
      const level = headerMatch[1].length;
      const headerText = headerMatch[2];
      blocks.push(/* @__PURE__ */ jsx(RenderHeader, { level, text: headerText }, key));
      return;
    }
    if (hrRegex.test(trimmedLine)) {
      blocks.push(
        /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Text, { color: "gray", children: "\u2500".repeat(40) }) }, key)
      );
      return;
    }
    const ulMatch = line.match(ulItemRegex);
    if (ulMatch && ulMatch[1] !== void 0 && ulMatch[3] !== void 0) {
      const indent = ulMatch[1].length;
      const itemText = ulMatch[3];
      blocks.push(
        /* @__PURE__ */ jsx(
          RenderListItem,
          {
            indent,
            marker: "-",
            text: itemText,
            defaultColor
          },
          key
        )
      );
      return;
    }
    const olMatch = line.match(olItemRegex);
    if (olMatch && olMatch[1] !== void 0 && olMatch[2] && olMatch[3] !== void 0) {
      const indent = olMatch[1].length;
      const number = olMatch[2];
      const itemText = olMatch[3];
      blocks.push(
        /* @__PURE__ */ jsx(
          RenderListItem,
          {
            indent,
            marker: `${number}.`,
            text: itemText,
            defaultColor
          },
          key
        )
      );
      return;
    }
    if (trimmedLine.length === 0) {
      blocks.push(/* @__PURE__ */ jsx(Box, { height: 1 }, key));
      return;
    }
    const usePrefix = isFirstContentLine && bulletPrefix;
    blocks.push(
      /* @__PURE__ */ jsx(
        WrappedParagraph,
        {
          text: line,
          defaultColor,
          ...bulletPrefix && { bulletPrefix },
          isFirstParagraph: usePrefix ? true : false
        },
        key
      )
    );
    if (usePrefix) {
      isFirstContentLine = false;
    }
  });
  if (inCodeBlock && codeBlockLines.length > 0) {
    blocks.push(
      /* @__PURE__ */ jsx(
        RenderCodeBlock,
        {
          lines: codeBlockLines,
          language: codeBlockLang,
          isPending: true
        },
        "code-pending"
      )
    );
  }
  return /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: blocks });
};
const RenderHeaderInternal = ({ level, text }) => {
  const headerColors = {
    1: "blue",
    2: "cyan",
    3: "white",
    4: "gray",
    5: "gray",
    6: "gray"
  };
  const headerColor = headerColors[level] || "white";
  return /* @__PURE__ */ jsx(Box, { marginTop: level <= 2 ? 1 : 0, children: /* @__PURE__ */ jsx(RenderInline, { text, defaultColor: headerColor, bold: true }) });
};
const RenderHeader = memo(RenderHeaderInternal);
const RenderListItemInternal = ({
  indent,
  marker,
  text,
  defaultColor
}) => {
  const { stdout } = useStdout();
  const terminalWidth = stdout?.columns ?? 80;
  const paddingLeft = Math.floor(indent / 2);
  const markerWithSpace = `${marker} `;
  const markerWidth = stringWidth(markerWithSpace);
  const wrappedLines = useMemo(() => {
    const segments = parseInlineMarkdown(text);
    const ansiString = segmentsToAnsi(segments, defaultColor);
    const availableWidth = Math.max(20, terminalWidth - paddingLeft - markerWidth);
    const wrapped = wrapAnsi(ansiString, availableWidth, {
      hard: false,
      wordWrap: true,
      trim: false
    });
    return wrapped.split("\n");
  }, [text, defaultColor, terminalWidth, paddingLeft, markerWidth]);
  const continuationIndent = " ".repeat(markerWidth);
  return /* @__PURE__ */ jsx(Box, { paddingLeft, flexDirection: "column", children: wrappedLines.map((line, i) => /* @__PURE__ */ jsxs(Box, { flexDirection: "row", children: [
    /* @__PURE__ */ jsx(Text, { color: defaultColor, children: i === 0 ? markerWithSpace : continuationIndent }),
    /* @__PURE__ */ jsx(Text, { children: line })
  ] }, i)) });
};
const RenderListItem = memo(RenderListItemInternal);
const RenderCodeBlockInternal = ({
  lines,
  language,
  isPending
}) => {
  const highlightedCode = useMemo(() => {
    const code = lines.join("\n");
    if (language && supportsLanguage(language)) {
      try {
        return highlight(code, { language, ignoreIllegals: true });
      } catch {
        return chalk.cyan(code);
      }
    }
    if (!language && code.trim()) {
      try {
        return highlight(code, { ignoreIllegals: true });
      } catch {
        return chalk.cyan(code);
      }
    }
    return chalk.cyan(code);
  }, [lines, language]);
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, marginBottom: 1, children: [
    language && /* @__PURE__ */ jsx(Text, { color: "gray", children: language }),
    /* @__PURE__ */ jsxs(Box, { flexDirection: "column", paddingLeft: 1, children: [
      /* @__PURE__ */ jsx(Text, { children: highlightedCode }),
      isPending && /* @__PURE__ */ jsx(Text, { color: "gray", children: "..." })
    ] })
  ] });
};
const RenderCodeBlock = memo(RenderCodeBlockInternal);
const MarkdownText = memo(MarkdownTextInternal);
export {
  MarkdownText,
  RenderInline,
  parseInlineMarkdown
};
