import React from "react";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";

interface MarkdownBlockProps {
    content: string;
}

import { Components } from "react-markdown";

const SafeLink: Components["a"] = ({ href, children, ...rest }) => {
  const rawHref = typeof href === "string" ? href.trim() : "";
  const normalized = rawHref.toLowerCase();
  const isAllowed =
    normalized.startsWith("https://") || normalized.startsWith("mailto:");

  if (!isAllowed) {
    return <span>{children}</span>;
  }

  return (
    <a {...rest} href={rawHref} target="_blank" rel="noopener noreferrer">
      {children}
    </a>
  );
};

const SanitizedImage: Components["img"] = ({ alt }) => {
  if (typeof alt === "string" && alt.trim().length > 0) {
    return <span>{alt}</span>;
  }
  return null;
};

// Minimal remark plugin to convert raw HTML <br> nodes to mdast hard breaks.
// This preserves line breaks inside table cells without enabling arbitrary HTML.
function remarkHtmlBrToBreak() {
  return (tree: any) => {
    const walk = (node: any) => {
      if (!node) return;
      if (node.type === 'html' && typeof node.value === 'string') {
        const raw = node.value.trim().toLowerCase();
        if (/^<br\s*\/?\s*>$/.test(raw)) {
          node.type = 'break';
          delete node.value;
        } else {
          // Render other raw HTML as plain text to avoid showing tags as elements
          node.type = 'text';
          // keep original text
        }
      }
      if (Array.isArray(node.children)) {
        for (const child of node.children) walk(child);
      }
    };
    walk(tree);
  };
}

const MarkdownBlock: React.FC<MarkdownBlockProps> = React.memo(({ content }) => {
    const markdown = content || '';
    return (
      <ReactMarkdown
        className="markdown"
        remarkPlugins={[remarkGfm, remarkHtmlBrToBreak]}
        components={{
          a: SafeLink,
          img: SanitizedImage,
        }}
      >
        {markdown}
      </ReactMarkdown>
    );
  });

export default MarkdownBlock;
