import {
	BarChart3Icon,
	BotIcon,
	ChevronDownIcon,
	LogOutIcon,
	UserIcon,
} from "lucide-react";
import { Popover as PopoverPrimitive } from "radix-ui";
import type * as React from "react";
import { useEffect, useState } from "react";
import type { ClawAccount } from "@/app/claw-account-gate";
import { ThreadList } from "@/components/assistant-ui/thread-list";
import { Button } from "@/components/ui/button";
import {
	Sidebar,
	SidebarContent,
	SidebarFooter,
	SidebarHeader,
	SidebarMenu,
	SidebarMenuButton,
	SidebarMenuItem,
	SidebarRail,
} from "@/components/ui/sidebar";

type ThreadListSidebarProps = React.ComponentProps<typeof Sidebar> & {
	account: ClawAccount;
	onLogout: () => void;
};

type ClawState = {
	model?: string;
	session_directory?: string;
	active_session_id?: string | null;
};

type ClawSessionSummary = {
	session_id: string;
	turns: number;
	tool_calls: number;
	modified_at: number;
	model?: string;
	usage?: UsageSummary;
};

type UsageSummary = {
	input_tokens?: number;
	output_tokens?: number;
	total_tokens?: number;
};

type ClawStoredSession = {
	session_id: string;
	usage?: UsageSummary;
	tool_calls?: number;
	turns?: number;
	model?: string;
};

export function ThreadListSidebar({
	account,
	onLogout,
	...props
}: ThreadListSidebarProps) {
	return (
		<Sidebar {...props}>
			<SidebarHeader className="aui-sidebar-header mb-2 border-b">
				<div className="aui-sidebar-header-content flex items-center justify-between">
					<SidebarMenu>
						<SidebarMenuItem>
							<SidebarMenuButton size="lg">
								<div className="aui-sidebar-header-icon-wrapper flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground">
									<BotIcon className="aui-sidebar-header-icon size-4" />
								</div>
								<div className="aui-sidebar-header-heading mr-6 flex flex-col gap-0.5 leading-none">
									<span className="aui-sidebar-header-title font-semibold">
										ZK Data Agent
									</span>
									<span className="text-muted-foreground text-xs">
										中控数据开发平台
									</span>
								</div>
							</SidebarMenuButton>
						</SidebarMenuItem>
					</SidebarMenu>
				</div>
			</SidebarHeader>
			<SidebarContent className="aui-sidebar-content px-2">
				<ThreadList />
			</SidebarContent>
			<SidebarRail />
			<SidebarFooter className="aui-sidebar-footer border-t">
				<AccountMenu account={account} onLogout={onLogout} />
			</SidebarFooter>
		</Sidebar>
	);
}

function AccountMenu({
	account,
	onLogout,
}: {
	account: ClawAccount;
	onLogout: () => void;
}) {
	const [open, setOpen] = useState(false);
	const [state, setState] = useState<ClawState | null>(null);
	const [sessions, setSessions] = useState<ClawSessionSummary[]>([]);
	const [activeSession, setActiveSession] = useState<ClawStoredSession | null>(
		null,
	);
	const [modelUsageOpen, setModelUsageOpen] = useState(false);

	useEffect(() => {
		if (!open) return;
		Promise.all([
			fetch("/api/claw/state", { cache: "no-store" }).then((res) =>
				res.ok ? res.json() : null,
			),
			fetch("/api/claw/sessions", { cache: "no-store" }).then((res) =>
				res.ok ? res.json() : [],
			),
		])
			.then(async ([statePayload, sessionsPayload]) => {
				const nextState = statePayload as ClawState | null;
				const nextSessions = Array.isArray(sessionsPayload)
					? (sessionsPayload as ClawSessionSummary[])
					: [];
				setState(nextState);
				setSessions(nextSessions);
				const activeSessionId =
					window.localStorage.getItem("claw.activeSessionId") ??
					nextState?.active_session_id;
				if (!activeSessionId) {
					setActiveSession(null);
					return;
				}
				const response = await fetch(`/api/claw/sessions/${activeSessionId}`, {
					cache: "no-store",
				});
				setActiveSession(response.ok ? await response.json() : null);
			})
			.catch(() => {
				setState(null);
				setSessions([]);
				setActiveSession(null);
			});
	}, [open]);

	async function logout() {
		await fetch("/api/claw/auth/logout", { method: "POST" });
		window.localStorage.removeItem("claw.activeSessionId");
		onLogout();
	}

	const totalToolCalls = sessions.reduce(
		(sum, session) => sum + (session.tool_calls ?? 0),
		0,
	);
	const modelUsage = aggregateUsageByModel(sessions);
	const modelUsageTotalTokens = modelUsage.reduce(
		(sum, item) => sum + item.totalTokens,
		0,
	);

	return (
		<PopoverPrimitive.Root open={open} onOpenChange={setOpen}>
			<PopoverPrimitive.Trigger asChild>
				<button
					type="button"
					className="flex w-full items-center gap-2 rounded-lg px-2 py-2 text-left transition-colors hover:bg-sidebar-accent"
				>
					<div className="flex size-8 shrink-0 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground">
						<UserIcon className="size-4" />
					</div>
					<div className="min-w-0 flex-1">
						<div className="truncate font-medium text-sm">
							{account.username}
						</div>
						<div className="text-muted-foreground text-xs">账号与统计</div>
					</div>
				</button>
			</PopoverPrimitive.Trigger>
			<PopoverPrimitive.Portal>
				<PopoverPrimitive.Content
					side="top"
					align="start"
					sideOffset={8}
					className="z-50 w-80 rounded-lg border bg-popover p-3 text-popover-foreground shadow-md outline-none"
				>
					<div className="mb-3 flex items-center gap-2">
						<div className="flex size-9 items-center justify-center rounded-lg bg-primary text-primary-foreground">
							<UserIcon className="size-4" />
						</div>
						<div className="min-w-0">
							<div className="truncate font-medium">{account.username}</div>
							<div className="truncate text-muted-foreground text-xs">
								{state?.model ?? "模型配置读取中"}
							</div>
						</div>
					</div>
					<div className="grid grid-cols-3 gap-2">
						<AccountStat label="会话" value={sessions.length} />
						<AccountStat label="工具" value={totalToolCalls} />
						<AccountStat
							label="Token"
							value={activeSession?.usage?.total_tokens ?? "暂无"}
						/>
					</div>
					<div className="mt-3 rounded-md border bg-muted/30 p-2 text-xs">
						<div className="mb-1 flex items-center gap-1.5 font-medium">
							<BarChart3Icon className="size-3.5" />
							当前会话
						</div>
						<div className="grid grid-cols-2 gap-x-3 gap-y-1 text-muted-foreground">
							<span>输入 token</span>
							<span className="text-right">
								{activeSession?.usage?.input_tokens ?? "暂无"}
							</span>
							<span>输出 token</span>
							<span className="text-right">
								{activeSession?.usage?.output_tokens ?? "暂无"}
							</span>
							<span>工具调用</span>
							<span className="text-right">
								{activeSession?.tool_calls ?? "暂无"}
							</span>
						</div>
					</div>
					<div className="mt-3 rounded-md border bg-muted/30 p-2 text-xs">
						<button
							type="button"
							className="flex w-full items-center justify-between gap-2 text-left"
							onClick={() => setModelUsageOpen((value) => !value)}
						>
							<span className="font-medium">按模型统计</span>
							<span className="flex items-center gap-1 text-muted-foreground">
								{modelUsage.length
									? `${modelUsage.length} 个模型 · ${formatCompactNumber(modelUsageTotalTokens)} tokens`
									: "暂无"}
								<ChevronDownIcon
									className={`size-3.5 transition-transform ${
										modelUsageOpen ? "rotate-180" : ""
									}`}
								/>
							</span>
						</button>
						{modelUsageOpen && modelUsage.length ? (
							<div className="mt-2 flex max-h-48 flex-col gap-2 overflow-y-auto pr-1">
								{modelUsage.map((item) => (
									<div
										key={item.model}
										className="grid grid-cols-[1fr_auto] gap-2"
									>
										<span className="truncate text-muted-foreground">
											{item.model}
										</span>
										<span>{formatCompactNumber(item.totalTokens)} tokens</span>
										<span className="text-muted-foreground">
											{item.sessions} 会话 · {item.toolCalls} 工具
										</span>
										<span className="text-right text-muted-foreground">
											in {formatCompactNumber(item.inputTokens)} / out{" "}
											{formatCompactNumber(item.outputTokens)}
										</span>
									</div>
								))}
							</div>
						) : null}
						{modelUsageOpen && !modelUsage.length ? (
							<div className="text-muted-foreground">暂无可统计会话</div>
						) : null}
					</div>
					<Button
						variant="ghost"
						className="mt-3 w-full justify-start gap-2 text-muted-foreground"
						onClick={logout}
					>
						<LogOutIcon className="size-4" />
						退出登录
					</Button>
				</PopoverPrimitive.Content>
			</PopoverPrimitive.Portal>
		</PopoverPrimitive.Root>
	);
}

function aggregateUsageByModel(sessions: ClawSessionSummary[]) {
	const byModel = new Map<
		string,
		{
			model: string;
			sessions: number;
			toolCalls: number;
			inputTokens: number;
			outputTokens: number;
			totalTokens: number;
		}
	>();
	for (const session of sessions) {
		const model = session.model || "unknown";
		const current = byModel.get(model) ?? {
			model,
			sessions: 0,
			toolCalls: 0,
			inputTokens: 0,
			outputTokens: 0,
			totalTokens: 0,
		};
		current.sessions += 1;
		current.toolCalls += session.tool_calls ?? 0;
		current.inputTokens += session.usage?.input_tokens ?? 0;
		current.outputTokens += session.usage?.output_tokens ?? 0;
		current.totalTokens +=
			session.usage?.total_tokens ??
			(session.usage?.input_tokens ?? 0) + (session.usage?.output_tokens ?? 0);
		byModel.set(model, current);
	}
	return [...byModel.values()].sort((a, b) => b.totalTokens - a.totalTokens);
}

function formatCompactNumber(value: number) {
	return new Intl.NumberFormat("en", {
		notation: "compact",
		maximumFractionDigits: 1,
	}).format(value);
}

function AccountStat({
	label,
	value,
}: {
	label: string;
	value: string | number;
}) {
	return (
		<div className="rounded-md border bg-muted/30 px-2 py-1.5">
			<div className="font-medium text-sm">{value}</div>
			<div className="text-muted-foreground text-xs">{label}</div>
		</div>
	);
}
