"use client";
import { useEffect, useRef, useState } from "react";
import { LuX, LuTerminal, LuSend } from "react-icons/lu";

export interface LogEntry {
	id: number;
	method: string;
	path: string;
	url: string;
	status: number | null;
	duration: number | null;
	timestamp: string;
	response: string | null;
}

interface DevConsoleProps {
	open: boolean;
	width: number;
	isMobile: boolean;
	onClose: () => void;
	onWidthChange: (w: number) => void;
	logs: LogEntry[];
}

function tryPretty(text: string): string {
	try {
		return JSON.stringify(JSON.parse(text), null, 2);
	} catch {
		return text;
	}
}

function methodBg(method: string): string {
	switch (method) {
		case "GET": return "#2563eb";
		case "POST": return "#16a34a";
		case "PUT": return "#d97706";
		case "PATCH": return "#7c3aed";
		case "DELETE": return "#dc2626";
		default: return "#6b7280";
	}
}

export default function DevConsole({
	open, width, isMobile, onClose, onWidthChange, logs,
}: DevConsoleProps) {
	const [activeTab, setActiveTab] = useState<"logs" | "request">("logs");
	const [expandedId, setExpandedId] = useState<number | null>(null);
	const [reqMethod, setReqMethod] = useState("GET");
	const [reqUrl, setReqUrl] = useState("/api/power");
	const [reqBody, setReqBody] = useState("");
	const [reqResponse, setReqResponse] = useState<{ status: number; body: string } | null>(null);
	const [reqLoading, setReqLoading] = useState(false);

	const dragRef = useRef<{ startX: number; startWidth: number } | null>(null);

	useEffect(() => {
		const onMove = (e: MouseEvent) => {
			if (!dragRef.current) return;
			const delta = dragRef.current.startX - e.clientX;
			const next = Math.max(300, Math.min(900, dragRef.current.startWidth + delta));
			onWidthChange(next);
		};
		const onUp = () => {
			if (!dragRef.current) return;
			dragRef.current = null;
			document.body.style.userSelect = "";
			document.body.style.cursor = "";
		};
		document.addEventListener("mousemove", onMove);
		document.addEventListener("mouseup", onUp);
		return () => {
			document.removeEventListener("mousemove", onMove);
			document.removeEventListener("mouseup", onUp);
		};
	}, [onWidthChange]);

	async function sendRequest() {
		setReqLoading(true);
		setReqResponse(null);
		try {
			const isAbsolute = reqUrl.startsWith("http://") || reqUrl.startsWith("https://");
			let fetchUrl: string;
			let fetchInit: RequestInit;

			if (isAbsolute) {
				fetchUrl = "/api/dev/proxy";
				fetchInit = {
					method: "POST",
					headers: { "Content-Type": "application/json" },
					body: JSON.stringify({ method: reqMethod, url: reqUrl, body: reqBody || undefined }),
				};
			} else {
				fetchUrl = reqUrl;
				fetchInit = {
					method: reqMethod,
					headers: reqBody ? { "Content-Type": "application/json" } : {},
					body: ["POST", "PUT", "PATCH"].includes(reqMethod) && reqBody ? reqBody : undefined,
				};
			}

			const res = await fetch(fetchUrl, fetchInit);
			const text = await res.text();
			setReqResponse({ status: res.status, body: tryPretty(text) });
		} catch (e) {
			setReqResponse({ status: 0, body: String(e) });
		} finally {
			setReqLoading(false);
		}
	}

	const panelWidth = isMobile ? "100%" : `${width}px`;
	const panelLeft = isMobile ? "0" : "auto";

	return (
		<div
			style={{
				position: "fixed",
				top: 0,
				right: 0,
				bottom: 0,
				left: panelLeft,
				width: panelWidth,
				zIndex: 50,
				display: "flex",
				flexDirection: "column",
				background: "#ffffff",
				borderLeft: "1px solid #e5e7eb",
				boxShadow: "-4px 0 24px rgba(0,0,0,0.06)",
				transform: open ? "translateX(0)" : "translateX(100%)",
				transition: "transform 280ms cubic-bezier(0.4,0,0.2,1)",
			}}
		>
			{/* Drag handle — desktop only */}
			{!isMobile && (
				<div
					style={{
						position: "absolute",
						left: 0,
						top: 0,
						bottom: 0,
						width: "4px",
						cursor: "col-resize",
						zIndex: 10,
					}}
					onMouseDown={(e) => {
						e.preventDefault();
						dragRef.current = { startX: e.clientX, startWidth: width };
						document.body.style.userSelect = "none";
						document.body.style.cursor = "col-resize";
					}}
				/>
			)}

			{/* Header */}
			<div style={{
				display: "flex",
				alignItems: "center",
				gap: "8px",
				padding: "10px 14px",
				borderBottom: "1px solid #e5e7eb",
				flexShrink: 0,
				background: "#ffffff",
			}}>
				<LuTerminal size={13} style={{ color: "#9ca3af" }} />
				<span style={{
					fontSize: "0.65rem",
					fontWeight: 700,
					letterSpacing: "0.1em",
					textTransform: "uppercase",
					color: "#9ca3af",
				}}>
					Dev Console
				</span>

				<div style={{ marginLeft: "auto", display: "flex", alignItems: "center", gap: "4px" }}>
					{(["logs", "request"] as const).map((tab) => (
						<button
							key={tab}
							onClick={() => setActiveTab(tab)}
							style={{
								fontSize: "0.68rem",
								fontWeight: 500,
								padding: "3px 9px",
								borderRadius: "6px",
								border: "none",
								cursor: "pointer",
								background: activeTab === tab ? "#f3f4f6" : "transparent",
								color: activeTab === tab ? "#111827" : "#9ca3af",
								textTransform: "capitalize",
							}}
						>
							{tab === "logs" ? `Logs${logs.length > 0 ? ` (${logs.length})` : ""}` : "Request"}
						</button>
					))}
					<button
						onClick={onClose}
						style={{
							marginLeft: "4px",
							background: "transparent",
							border: "none",
							cursor: "pointer",
							color: "#9ca3af",
							display: "flex",
							alignItems: "center",
							padding: "2px",
						}}
					>
						<LuX size={13} />
					</button>
				</div>
			</div>

			{/* Logs tab */}
			{activeTab === "logs" && (
				<div style={{ flex: 1, overflowY: "auto", fontFamily: "ui-monospace, 'Cascadia Code', monospace" }}>
					{logs.length === 0 ? (
						<div style={{ padding: "32px 16px", textAlign: "center", color: "#d1d5db", fontSize: "0.75rem" }}>
							No requests captured yet
						</div>
					) : (
						[...logs].reverse().map((entry) => (
							<LogRow
								key={entry.id}
								entry={entry}
								expanded={expandedId === entry.id}
								onToggle={() => setExpandedId(expandedId === entry.id ? null : entry.id)}
							/>
						))
					)}
				</div>
			)}

			{/* Request tab */}
			{activeTab === "request" && (
				<div style={{ flex: 1, display: "flex", flexDirection: "column", overflow: "hidden" }}>
					<div style={{ padding: "12px", borderBottom: "1px solid #e5e7eb", flexShrink: 0 }}>
						<div style={{ display: "flex", gap: "6px", marginBottom: "8px" }}>
							<select
								value={reqMethod}
								onChange={(e) => setReqMethod(e.target.value)}
								style={{
									background: "#f9fafb",
									border: "1px solid #e5e7eb",
									borderRadius: "8px",
									color: "#111827",
									fontSize: "0.68rem",
									padding: "5px 6px",
									cursor: "pointer",
									fontFamily: "ui-monospace, monospace",
									outline: "none",
								}}
							>
								{["GET", "POST", "PUT", "PATCH", "DELETE"].map((m) => (
									<option key={m}>{m}</option>
								))}
							</select>
							<input
								value={reqUrl}
								onChange={(e) => setReqUrl(e.target.value)}
								onKeyDown={(e) => e.key === "Enter" && sendRequest()}
								placeholder="/api/power"
								style={{
									flex: 1,
									background: "#f9fafb",
									border: "1px solid #e5e7eb",
									borderRadius: "8px",
									color: "#111827",
									fontSize: "0.68rem",
									padding: "5px 8px",
									fontFamily: "ui-monospace, monospace",
									outline: "none",
									minWidth: 0,
								}}
							/>
							<button
								onClick={sendRequest}
								disabled={reqLoading}
								style={{
									background: "#2563eb",
									border: "none",
									borderRadius: "8px",
									color: "white",
									padding: "5px 11px",
									cursor: reqLoading ? "default" : "pointer",
									display: "flex",
									alignItems: "center",
									gap: "4px",
									fontSize: "0.68rem",
									fontWeight: 500,
									opacity: reqLoading ? 0.6 : 1,
									flexShrink: 0,
								}}
							>
								<LuSend size={11} />
								Send
							</button>
						</div>

						{["POST", "PUT", "PATCH"].includes(reqMethod) && (
							<textarea
								value={reqBody}
								onChange={(e) => setReqBody(e.target.value)}
								placeholder='{"key": "value"}'
								rows={4}
								style={{
									width: "100%",
									background: "#f9fafb",
									border: "1px solid #e5e7eb",
									borderRadius: "8px",
									color: "#111827",
									fontSize: "0.68rem",
									padding: "6px 8px",
									fontFamily: "ui-monospace, monospace",
									resize: "vertical",
									outline: "none",
									boxSizing: "border-box",
									marginBottom: "8px",
								}}
							/>
						)}

						<div style={{ fontSize: "0.6rem", color: "#d1d5db" }}>
							Bearer token attached via cookie ·{" "}
							<span style={{ color: "#9ca3af" }}>use</span>{" "}
							<code style={{ color: "#6b7280" }}>http://localhost:3001/path</code>{" "}
							<span style={{ color: "#9ca3af" }}>to bypass Next.js proxy</span>
						</div>
					</div>

					<div style={{
						flex: 1,
						overflow: "auto",
						padding: "12px",
						fontFamily: "ui-monospace, 'Cascadia Code', monospace",
						background: "#f9fafb",
					}}>
						{reqLoading && (
							<div style={{ fontSize: "0.7rem", color: "#9ca3af" }}>Sending…</div>
						)}
						{!reqLoading && reqResponse && (
							<>
								<div style={{
									fontSize: "0.65rem",
									fontWeight: 600,
									marginBottom: "8px",
									color: reqResponse.status >= 200 && reqResponse.status < 300 ? "#16a34a" : "#dc2626",
								}}>
									HTTP {reqResponse.status}
								</div>
								<pre style={{
									fontSize: "0.65rem",
									color: "#6b7280",
									margin: 0,
									whiteSpace: "pre-wrap",
									wordBreak: "break-all",
									lineHeight: 1.6,
								}}>
									{reqResponse.body}
								</pre>
							</>
						)}
						{!reqLoading && !reqResponse && (
							<div style={{ fontSize: "0.7rem", color: "#d1d5db" }}>
								Response will appear here
							</div>
						)}
					</div>
				</div>
			)}
		</div>
	);
}

function LogRow({
	entry,
	expanded,
	onToggle,
}: {
	entry: LogEntry;
	expanded: boolean;
	onToggle: () => void;
}) {
	const [hovered, setHovered] = useState(false);
	const statusColor =
		entry.status === null
			? "#9ca3af"
			: entry.status >= 200 && entry.status < 300
			? "#16a34a"
			: "#dc2626";

	return (
		<div style={{ borderBottom: "1px solid #f3f4f6" }}>
			<div
				onClick={onToggle}
				onMouseEnter={() => setHovered(true)}
				onMouseLeave={() => setHovered(false)}
				style={{
					display: "flex",
					alignItems: "center",
					gap: "8px",
					padding: "6px 12px",
					cursor: "pointer",
					background: hovered ? "#f9fafb" : "transparent",
				}}
			>
				<span style={{
					fontSize: "0.58rem",
					fontWeight: 700,
					padding: "1px 5px",
					borderRadius: "4px",
					minWidth: "38px",
					textAlign: "center",
					background: methodBg(entry.method),
					color: "white",
					flexShrink: 0,
					letterSpacing: "0.02em",
				}}>
					{entry.method}
				</span>
				<span style={{
					fontSize: "0.63rem",
					fontWeight: 600,
					minWidth: "26px",
					textAlign: "right",
					color: statusColor,
					flexShrink: 0,
				}}>
					{entry.status ?? "···"}
				</span>
				<span style={{
					fontSize: "0.68rem",
					color: "#6b7280",
					flex: 1,
					overflow: "hidden",
					textOverflow: "ellipsis",
					whiteSpace: "nowrap",
				}}>
					{entry.path}
				</span>
				<span style={{ fontSize: "0.6rem", color: "#9ca3af", flexShrink: 0 }}>
					{entry.duration !== null ? `${entry.duration}ms` : ""}
				</span>
				<span style={{ fontSize: "0.6rem", color: "#d1d5db", flexShrink: 0 }}>
					{entry.timestamp}
				</span>
			</div>

			{expanded && (
				<div style={{
					background: "#f9fafb",
					padding: "8px 12px 10px",
					borderTop: "1px solid #e5e7eb",
				}}>
					<div style={{
						fontSize: "0.6rem",
						color: "#9ca3af",
						marginBottom: "6px",
						wordBreak: "break-all",
					}}>
						{entry.url}
					</div>
					{entry.response !== null && (
						<pre style={{
							fontSize: "0.63rem",
							color: "#6b7280",
							margin: 0,
							overflow: "auto",
							maxHeight: "220px",
							whiteSpace: "pre-wrap",
							wordBreak: "break-all",
							lineHeight: 1.5,
						}}>
							{(() => {
								try { return JSON.stringify(JSON.parse(entry.response), null, 2); }
								catch { return entry.response; }
							})()}
						</pre>
					)}
				</div>
			)}
		</div>
	);
}
