import type { ToolInput } from "../../core/io/input-types";
import type { ToolResult } from "../../core/io/output-types";
import type { ToolContext } from "../../core/plugins/plugin-types";
import type { MarkdownToHtmlOptions } from "./index";

function convertMarkdown(md: string): string {
  let html = md;

  html = html.replace(/^### (.+)$/gm, "<h3>$1</h3>");
  html = html.replace(/^## (.+)$/gm, "<h2>$1</h2>");
  html = html.replace(/^# (.+)$/gm, "<h1>$1</h1>");

  html = html.replace(/\*\*\*(.+?)\*\*\*/g, "<strong><em>$1</em></strong>");
  html = html.replace(/\*\*(.+?)\*\*/g, "<strong>$1</strong>");
  html = html.replace(/\*(.+?)\*/g, "<em>$1</em>");
  html = html.replace(/~~(.+?)~~/g, "<del>$1</del>");

  html = html.replace(/`([^`]+)`/g, "<code>$1</code>");

  html = html.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, '<img src="$2" alt="$1">');

  html = html.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2">$1</a>');

  html = html.replace(/^>\s(.+)$/gm, "<blockquote>$1</blockquote>");

  html = html.replace(/^---$/gm, "<hr>");

  html = html.replace(/^\s*[-*+]\s(.+)$/gm, "<li>$1</li>");
  html = html.replace(/(<li>.*<\/li>\n?)+/g, (match) => `<ul>\n${match}</ul>\n`);

  html = html.replace(/^\s*\d+\.\s(.+)$/gm, "<li>$1</li>");

  html = html.replace(/\n{2,}/g, "\n</p>\n<p>\n");
  html = `<p>${html}</p>`;

  html = html.replace(/<p>\s*<(h[1-6]|ul|ol|blockquote|hr)/g, "<$1");
  html = html.replace(/<\/(h[1-6]|ul|ol|blockquote|hr)>\s*<\/p>/g, "</$1>");

  html = html.replace(/<p>\s*<\/p>/g, "");

  return html.trim();
}

export async function runMarkdownToHtml(
  input: ToolInput,
  _options: MarkdownToHtmlOptions,
  context: ToolContext
): Promise<ToolResult> {
  const text = input.text || "";
  if (!text.trim()) {
    throw new Error("No Markdown text provided.");
  }

  context.reportProgress({ percentage: 50, message: "Converting..." });

  const html = convertMarkdown(text);

  context.reportProgress({ percentage: 100, message: "Done" });

  return {
    type: "text",
    value: html,
    language: "html",
  };
}
