import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";
import { ArtifactPreview } from "./ArtifactPreview.jsx";
import { CodeBlock } from "./CodeBlock.jsx";
import { artifactInfo, assistantSegments } from "./assistant-artifacts.js";

function isExternalWebUrl(href) {
  try {
    const url = new URL(href);
    return url.protocol === "https:" || url.protocol === "http:";
  } catch {
    return false;
  }
}

const components = {
  a: ({ node: _node, href = "", children, ...props }) => {
    const artifact = artifactInfo(href);
    if (artifact) return <a
      {...props}
      className="artifact-link"
      href={artifact.url}
      download={artifact.mimeType === "application/zip" ? artifact.name : undefined}
      target={artifact.mimeType === "application/zip" ? undefined : "_blank"}
      rel="noreferrer noopener"
    >
      <span className="artifact-link-copy"><strong>{children}</strong><small>{artifact.name}{artifact.line ? ` · line ${artifact.line}` : ""}</small></span>
      <span className="artifact-link-size">{formatBytes(artifact.size)}</span>
    </a>;
    return isExternalWebUrl(href)
      ? <a {...props} href={href} target="_blank" rel="noreferrer noopener">{children}</a>
      : <span className="markdown-unavailable-link" title="This local link is not available in the browser">{children}</span>;
  },
  img: ({ node: _node, src = "", ...props }) => {
    const artifact = artifactInfo(src);
    if (!artifact) return <span className="markdown-unavailable-image" role="img" aria-label={props.alt || "Image unavailable"}>{props.alt || "Image unavailable"}</span>;
    return <img {...props} src={artifact.url} loading="lazy" />;
  },
  pre: ({ node: _node, children, ...props }) => {
    const code = Array.isArray(children) ? children[0] : children;
    const content = code?.props?.children;
    const text = Array.isArray(content) ? content.join("") : String(content ?? "");
    return text.trim() ? <CodeBlock {...props} text={text}>{children}</CodeBlock> : null;
  },
  table: ({ node: _node, ...props }) => <div className="table-scroll"><table {...props} /></div>
};

export function AssistantMarkdown({ children }) {
  return <div className="message assistant markdown-body">
    {assistantSegments(children).map((segment, index) => segment.kind === "html"
      ? <ArtifactPreview key={`${segment.id}-${index}`} artifact={segment} />
      : <ReactMarkdown key={`markdown-${index}`} remarkPlugins={[remarkGfm]} components={components}>{segment.text}</ReactMarkdown>)}
  </div>;
}

function formatBytes(value) {
  if (!Number.isFinite(value)) return "";
  if (value < 1024) return `${value} B`;
  if (value < 1024 * 1024) return `${Math.round(value / 1024)} KB`;
  return `${(value / (1024 * 1024)).toFixed(1)} MB`;
}
