import * as React from "react";
import Markdown from "react-markdown";
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
import { oneDark } from "react-syntax-highlighter/dist/esm/styles/prism";
import type { Message, ToolCall } from "../types";
import { InlineCodeWithRefs } from "./CodeRef";

// biome-ignore lint/suspicious/noExplicitAny: react-markdown requires any for component props
function CodeBlock({ className, children, ...props }: any) {
	const match = /language-(\w+)/.exec(className || "");
	const isInline = !className;
	const text = String(children);
	if (!isInline && match) {
		return (
			<SyntaxHighlighter
				// biome-ignore lint/suspicious/noExplicitAny: oneDark style types are incompatible
				style={oneDark as any}
				language={match[1]}
				PreTag="div"
			>
				{text.replace(/\n$/, "")}
			</SyntaxHighlighter>
		);
	}
	// For inline code, detect and render code references as clickable links
	return (
		<code className={className} {...props}>
			<InlineCodeWithRefs text={text} />
		</code>
	);
}

interface MessageItemProps {
	msg: Message;
}

function MessageItemInner({ msg }: MessageItemProps) {
	return (
		<div
			style={{
				display: "flex",
				flexDirection: "column",
				alignItems: msg.role === "user" ? "flex-end" : "flex-start",
			}}
		>
			<div
				style={{
					maxWidth: "100%",
					padding: msg.role === "user" ? "10px 16px" : "0",
					borderRadius: msg.role === "user" ? "20px" : "0",
					background:
						msg.role === "user"
							? "#2f2f2f"
							: msg.role === "tool"
								? "#222"
								: "transparent",
					color: "#ececec",
					border: msg.role === "tool" ? "1px solid #333" : "none",
					fontFamily: msg.role === "tool" ? "monospace" : "inherit",
					fontSize: msg.role === "tool" ? "0.85em" : "1em",
					fontWeight: "500",
					whiteSpace: msg.role === "tool" ? "pre-wrap" : "normal",
					lineHeight: "1.6",
				}}
			>
				{msg.role === "user" ? (
					<div className="user-markdown-body">
						<Markdown components={{ code: CodeBlock }}>{msg.content}</Markdown>
					</div>
				) : msg.role === "tool" ? (
					<details style={{ cursor: "pointer" }}>
						<summary
							style={{
								color: "#aaa",
								fontSize: "0.9em",
								marginBottom: "8px",
								listStyle: "none",
								display: "flex",
								alignItems: "center",
								gap: "6px",
							}}
						>
							<span style={{ fontSize: "0.8em" }}>▶</span>
							<span>
								Tool Output
								{msg.tool_call_id && ` (${msg.tool_call_id})`}
							</span>
						</summary>
						<pre
							style={{
								maxHeight: "300px",
								overflow: "auto",
								margin: 0,
								padding: "8px",
								background: "#1a1a1a",
								borderRadius: "4px",
								fontSize: "0.85em",
								whiteSpace: "pre-wrap",
								wordBreak: "break-word",
							}}
						>
							{msg.content}
						</pre>
					</details>
				) : (
					<div className="markdown-body">
						<Markdown components={{ code: CodeBlock }}>{msg.content}</Markdown>
					</div>
				)}

				{msg.tool_calls && (
					<div
						style={{
							marginTop: "12px",
							fontSize: "0.85em",
							color: "#aaa",
							display: "flex",
							flexDirection: "column",
							gap: "8px",
						}}
					>
						{msg.tool_calls.map((tc: ToolCall, i: number) => {
							let argsSummary = "";
							try {
								const args = JSON.parse(tc.function.arguments);
								const firstKey = Object.keys(args)[0];
								if (firstKey && args[firstKey]) {
									argsSummary = String(args[firstKey]);
									if (argsSummary.length > 50) {
										argsSummary = `${argsSummary.substring(0, 47)}...`;
									}
								}
							} catch (_e) {
								// ignore
							}

							return (
								<div
									// biome-ignore lint/suspicious/noArrayIndexKey: ToolCall has no stable ID
									key={`tool-${i}-${tc.function.name}`}
									style={{
										display: "flex",
										alignItems: "center",
										gap: "8px",
										fontFamily: "monospace",
									}}
								>
									<span style={{ color: "#888" }}>▶</span>
									<span
										style={{
											background: "#333",
											padding: "2px 6px",
											borderRadius: "4px",
										}}
									>
										{tc.function.name}
										{argsSummary && `(${argsSummary})`}
									</span>
								</div>
							);
						})}
					</div>
				)}
			</div>
		</div>
	);
}

export const MessageItem = React.memo(MessageItemInner);
