import * as React from "react";
import Markdown from "react-markdown";
import type { AgentEvent, AgentInfo, AgentStatusValue } from "../api/agents";
import { agentsApi, subscribeAgentStream } from "../api/agents";
import { api } from "../api/client";

const { useEffect, useRef, useState } = React;

const STAGE_LABELS: Record<string, string> = {
	upcoming: "Upcoming",
	current: "Current",
	qa: "QA",
	merge: "To Merge",
	done: "Done",
	archived: "Archived",
};

const STATUS_COLORS: Record<AgentStatusValue, string> = {
	running: "#3fb950",
	pending: "#e3b341",
	completed: "#aaa",
	failed: "#f85149",
};

interface WorkItemDetailPanelProps {
	storyId: string;
	onClose: () => void;
}

export function WorkItemDetailPanel({
	storyId,
	onClose,
}: WorkItemDetailPanelProps) {
	const [content, setContent] = useState<string | null>(null);
	const [stage, setStage] = useState<string>("");
	const [name, setName] = useState<string | null>(null);
	const [loading, setLoading] = useState(true);
	const [error, setError] = useState<string | null>(null);
	const [agentInfo, setAgentInfo] = useState<AgentInfo | null>(null);
	const [agentLog, setAgentLog] = useState<string[]>([]);
	const [agentStatus, setAgentStatus] = useState<AgentStatusValue | null>(null);
	const panelRef = useRef<HTMLDivElement>(null);
	const cleanupRef = useRef<(() => void) | null>(null);

	useEffect(() => {
		setLoading(true);
		setError(null);
		api
			.getWorkItemContent(storyId)
			.then((data) => {
				setContent(data.content);
				setStage(data.stage);
				setName(data.name);
			})
			.catch((err: unknown) => {
				setError(err instanceof Error ? err.message : "Failed to load content");
			})
			.finally(() => {
				setLoading(false);
			});
	}, [storyId]);

	useEffect(() => {
		cleanupRef.current?.();
		cleanupRef.current = null;
		setAgentInfo(null);
		setAgentLog([]);
		setAgentStatus(null);

		agentsApi
			.listAgents()
			.then((agents) => {
				const agent = agents.find((a) => a.story_id === storyId);
				if (!agent) return;
				setAgentInfo(agent);
				setAgentStatus(agent.status);

				if (agent.status === "running" || agent.status === "pending") {
					const cleanup = subscribeAgentStream(
						storyId,
						agent.agent_name,
						(event: AgentEvent) => {
							switch (event.type) {
								case "status":
									setAgentStatus((event.status as AgentStatusValue) ?? null);
									break;
								case "output":
									setAgentLog((prev) => [...prev, event.text ?? ""]);
									break;
								case "done":
									setAgentStatus("completed");
									break;
								case "error":
									setAgentStatus("failed");
									setAgentLog((prev) => [
										...prev,
										`[ERROR] ${event.message ?? "Unknown error"}`,
									]);
									break;
								default:
									break;
							}
						},
					);
					cleanupRef.current = cleanup;
				}
			})
			.catch((err: unknown) => {
				console.error("Failed to load agents:", err);
			});

		return () => {
			cleanupRef.current?.();
			cleanupRef.current = null;
		};
	}, [storyId]);

	useEffect(() => {
		const handleKeyDown = (e: KeyboardEvent) => {
			if (e.key === "Escape") {
				onClose();
			}
		};
		window.addEventListener("keydown", handleKeyDown);
		return () => window.removeEventListener("keydown", handleKeyDown);
	}, [onClose]);

	const stageLabel = STAGE_LABELS[stage] ?? stage;

	return (
		<div
			data-testid="work-item-detail-panel"
			ref={panelRef}
			style={{
				display: "flex",
				flexDirection: "column",
				height: "100%",
				overflow: "hidden",
				background: "#1a1a1a",
				borderRadius: "8px",
				border: "1px solid #333",
			}}
		>
			{/* Header */}
			<div
				style={{
					display: "flex",
					alignItems: "center",
					justifyContent: "space-between",
					padding: "12px 16px",
					borderBottom: "1px solid #333",
					flexShrink: 0,
				}}
			>
				<div
					style={{
						display: "flex",
						flexDirection: "column",
						gap: "2px",
						minWidth: 0,
					}}
				>
					<div
						data-testid="detail-panel-title"
						style={{
							fontWeight: 600,
							fontSize: "0.95em",
							color: "#ececec",
							overflow: "hidden",
							textOverflow: "ellipsis",
							whiteSpace: "nowrap",
						}}
					>
						{name ?? storyId}
					</div>
					{stage && (
						<div
							data-testid="detail-panel-stage"
							style={{ fontSize: "0.75em", color: "#888" }}
						>
							{stageLabel}
						</div>
					)}
				</div>
				<button
					type="button"
					data-testid="detail-panel-close"
					onClick={onClose}
					style={{
						background: "none",
						border: "1px solid #444",
						borderRadius: "6px",
						color: "#aaa",
						cursor: "pointer",
						padding: "4px 10px",
						fontSize: "0.8em",
						flexShrink: 0,
					}}
				>
					Close
				</button>
			</div>

			{/* Scrollable content area */}
			<div
				style={{
					flex: 1,
					overflowY: "auto",
					padding: "16px",
					display: "flex",
					flexDirection: "column",
					gap: "16px",
				}}
			>
				{loading && (
					<div
						data-testid="detail-panel-loading"
						style={{ color: "#666", fontSize: "0.85em" }}
					>
						Loading...
					</div>
				)}
				{error && (
					<div
						data-testid="detail-panel-error"
						style={{ color: "#ff7b72", fontSize: "0.85em" }}
					>
						{error}
					</div>
				)}
				{!loading && !error && content !== null && (
					<div
						data-testid="detail-panel-content"
						className="markdown-body"
						style={{ fontSize: "0.9em", lineHeight: 1.6 }}
					>
						<Markdown
							components={{
								// biome-ignore lint/suspicious/noExplicitAny: react-markdown requires any for component props
								h1: ({ children }: any) => (
									<h1 style={{ fontSize: "1.2em" }}>{children}</h1>
								),
								// biome-ignore lint/suspicious/noExplicitAny: react-markdown requires any for component props
								h2: ({ children }: any) => (
									<h2 style={{ fontSize: "1.1em" }}>{children}</h2>
								),
								// biome-ignore lint/suspicious/noExplicitAny: react-markdown requires any for component props
								h3: ({ children }: any) => (
									<h3 style={{ fontSize: "1em" }}>{children}</h3>
								),
							}}
						>
							{content}
						</Markdown>
					</div>
				)}

				<div
					style={{
						display: "flex",
						flexDirection: "column",
						gap: "8px",
					}}
				>
					{/* Agent Logs section */}
					<div
						data-testid={
							agentInfo ? "agent-logs-section" : "placeholder-agent-logs"
						}
						style={{
							border: "1px solid #2a2a2a",
							borderRadius: "8px",
							padding: "10px 12px",
							background: "#161616",
						}}
					>
						<div
							style={{
								display: "flex",
								alignItems: "center",
								justifyContent: "space-between",
								marginBottom: agentInfo ? "6px" : "4px",
							}}
						>
							<div
								style={{
									fontWeight: 600,
									fontSize: "0.8em",
									color: agentInfo ? "#888" : "#555",
								}}
							>
								Agent Logs
							</div>
							{agentInfo && agentStatus && (
								<div
									data-testid="agent-status-badge"
									style={{
										fontSize: "0.7em",
										color: STATUS_COLORS[agentStatus],
										fontWeight: 600,
									}}
								>
									{agentInfo.agent_name} — {agentStatus}
								</div>
							)}
						</div>
						{agentInfo && agentLog.length > 0 ? (
							<div
								data-testid="agent-log-output"
								style={{
									fontSize: "0.75em",
									fontFamily: "monospace",
									color: "#ccc",
									whiteSpace: "pre-wrap",
									wordBreak: "break-word",
									lineHeight: "1.5",
									maxHeight: "200px",
									overflowY: "auto",
								}}
							>
								{agentLog.join("")}
							</div>
						) : agentInfo ? (
							<div style={{ fontSize: "0.75em", color: "#444" }}>
								{agentStatus === "running" || agentStatus === "pending"
									? "Waiting for output..."
									: "No output."}
							</div>
						) : (
							<div style={{ fontSize: "0.75em", color: "#444" }}>
								Coming soon
							</div>
						)}
					</div>

					{/* Placeholder sections for future content */}
					{(
						[
							{ id: "test-output", label: "Test Output" },
							{ id: "coverage", label: "Coverage" },
						] as { id: string; label: string }[]
					).map(({ id, label }) => (
						<div
							key={id}
							data-testid={`placeholder-${id}`}
							style={{
								border: "1px solid #2a2a2a",
								borderRadius: "8px",
								padding: "10px 12px",
								background: "#161616",
							}}
						>
							<div
								style={{
									fontWeight: 600,
									fontSize: "0.8em",
									color: "#555",
									marginBottom: "4px",
								}}
							>
								{label}
							</div>
							<div style={{ fontSize: "0.75em", color: "#444" }}>
								Coming soon
							</div>
						</div>
					))}
				</div>
			</div>
		</div>
	);
}
