import { useCallback, useEffect, useState } from "react";
import { toast } from "react-toastify";
import { admin } from "../api/client";
import type { AdminUser, AuditLog, Agent, GlobalSettings } from "../api/types";
import { useAuth } from "../context/AuthContext";
import { Button, Card, PageHeader, Spinner, Toggle } from "../components/ui";
import { relativeTime } from "../utils";

type Tab = "users" | "agents" | "settings" | "audit";

export function AdminPage() {
	const [tab, setTab] = useState<Tab>("users");
	const tabs: { id: Tab; label: string }[] = [
		{ id: "users", label: "Users" },
		{ id: "agents", label: "Agents" },
		{ id: "settings", label: "Global settings" },
		{ id: "audit", label: "Audit logs" },
	];

	return (
		<div>
			<PageHeader title="Admin" subtitle="Platform administration." />
			<div className="mb-6 flex gap-1 overflow-x-auto border-b border-border">
				{tabs.map((t) => (
					<button
						key={t.id}
						onClick={() => setTab(t.id)}
						className={`shrink-0 px-4 py-2 text-sm font-medium transition ${
							tab === t.id ? "border-b-2 border-accent text-text" : "text-muted hover:text-text"
						}`}
					>
						{t.label}
					</button>
				))}
			</div>
			{tab === "users" && <UsersTab />}
			{tab === "agents" && <AgentsTab />}
			{tab === "settings" && <SettingsTab />}
			{tab === "audit" && <AuditTab />}
		</div>
	);
}

function UsersTab() {
	const { user: me } = useAuth();
	const [users, setUsers] = useState<AdminUser[]>([]);
	const [loading, setLoading] = useState(true);

	const load = useCallback(async () => {
		try {
			setUsers(await admin.users());
		} finally {
			setLoading(false);
		}
	}, []);
	useEffect(() => {
		load();
	}, [load]);

	const setRole = async (u: AdminUser, role: "ADMIN" | "USER") => {
		try {
			await admin.updateUser(u.id, { role });
			toast.success("Role updated");
			load();
		} catch (e) {
			toast.error(e instanceof Error ? e.message : "Failed");
		}
	};
	const toggleDisabled = async (u: AdminUser) => {
		try {
			await admin.updateUser(u.id, { disabled: !u.disabled });
			load();
		} catch (e) {
			toast.error(e instanceof Error ? e.message : "Failed");
		}
	};
	const remove = async (u: AdminUser) => {
		if (!confirm(`Delete user "${u.username}" and all their data?`)) return;
		try {
			await admin.deleteUser(u.id);
			toast.success("User deleted");
			load();
		} catch (e) {
			toast.error(e instanceof Error ? e.message : "Failed");
		}
	};

	if (loading) return <Loader />;
	return (
		<div className="space-y-2">
			{users.map((u) => (
				<Card key={u.id} className="flex flex-wrap items-center gap-3 p-4">
					<div className="min-w-0 flex-1">
						<div className="flex items-center gap-2">
							<span className="font-medium text-text">{u.display_name}</span>
							<span className="text-xs text-faint">@{u.username}</span>
							{u.role === "ADMIN" && (
								<span className="rounded-full bg-accent/15 px-2 py-0.5 text-[10px] font-semibold text-accent">
									ADMIN
								</span>
							)}
							{u.disabled && (
								<span className="rounded-full bg-rejected/15 px-2 py-0.5 text-[10px] font-semibold text-rejected">
									DISABLED
								</span>
							)}
						</div>
						<p className="text-xs text-muted">
							{u.agent_count} agents · {u.request_count} requests · joined {relativeTime(u.created_at)}
						</p>
					</div>
					{u.id !== me?.id && (
						<div className="flex w-full flex-wrap gap-2 sm:w-auto sm:flex-nowrap">
							<Button variant="ghost" onClick={() => setRole(u, u.role === "ADMIN" ? "USER" : "ADMIN")}>
								{u.role === "ADMIN" ? "Demote" : "Promote"}
							</Button>
							<Button variant="ghost" onClick={() => toggleDisabled(u)}>
								{u.disabled ? "Enable" : "Disable"}
							</Button>
							<Button variant="ghost" className="text-rejected" onClick={() => remove(u)}>
								Delete
							</Button>
						</div>
					)}
				</Card>
			))}
		</div>
	);
}

function AgentsTab() {
	const [agents, setAgents] = useState<(Agent & { owner: { id: number; username: string } })[]>([]);
	const [loading, setLoading] = useState(true);
	const load = useCallback(async () => {
		try {
			setAgents(await admin.agents());
		} finally {
			setLoading(false);
		}
	}, []);
	useEffect(() => {
		load();
	}, [load]);

	const toggle = async (a: Agent) => {
		try {
			await admin.setAgentDisabled(a.id, !a.disabled);
			load();
		} catch (e) {
			toast.error(e instanceof Error ? e.message : "Failed");
		}
	};
	const remove = async (a: Agent) => {
		if (!confirm(`Delete agent "${a.name}"?`)) return;
		try {
			await admin.deleteAgent(a.id);
			toast.success("Agent deleted");
			load();
		} catch (e) {
			toast.error(e instanceof Error ? e.message : "Failed");
		}
	};

	if (loading) return <Loader />;
	return (
		<div className="space-y-2">
			{agents.map((a) => (
				<Card key={a.id} className="flex flex-wrap items-center gap-3 p-4">
					<div className="min-w-0 flex-1">
						<div className="flex items-center gap-2">
							<span className="font-medium text-text">{a.name}</span>
							<span className="text-xs text-faint">by @{a.owner.username}</span>
							{a.disabled && (
								<span className="rounded-full bg-rejected/15 px-2 py-0.5 text-[10px] font-semibold text-rejected">
									DISABLED
								</span>
							)}
						</div>
						{a.description && <p className="text-xs text-muted">{a.description}</p>}
					</div>
					<div className="flex w-full flex-wrap gap-2 sm:w-auto sm:flex-nowrap">
						<Button variant="ghost" onClick={() => toggle(a)}>
							{a.disabled ? "Enable" : "Disable"}
						</Button>
						<Button variant="ghost" className="text-rejected" onClick={() => remove(a)}>
							Delete
						</Button>
					</div>
				</Card>
			))}
		</div>
	);
}

function SettingsTab() {
	const [settings, setSettings] = useState<GlobalSettings | null>(null);
	useEffect(() => {
		admin.settings().then(setSettings).catch(() => {});
	}, []);

	const update = async (patch: Partial<GlobalSettings>) => {
		try {
			const res = await admin.updateSettings(patch);
			setSettings(res);
			toast.success("Settings updated");
		} catch (e) {
			toast.error(e instanceof Error ? e.message : "Failed");
		}
	};

	if (!settings) return <Loader />;
	return (
		<div className="space-y-3">
			<Card className="flex flex-wrap items-center justify-between gap-4 p-4 sm:p-5">
				<div>
					<p className="font-medium text-text">Enable registration</p>
					<p className="text-sm text-muted">Allow new humans to create accounts.</p>
				</div>
				<Toggle checked={settings.registration_enabled} onChange={(v) => update({ registration_enabled: v })} />
			</Card>
			<Card className="flex flex-wrap items-center justify-between gap-4 p-4 sm:p-5">
				<div>
					<p className="font-medium text-text">Enable requests</p>
					<p className="text-sm text-muted">Allow agents to submit new change requests platform-wide.</p>
				</div>
				<Toggle checked={settings.requests_enabled} onChange={(v) => update({ requests_enabled: v })} />
			</Card>
		</div>
	);
}

function AuditTab() {
	const [logs, setLogs] = useState<AuditLog[]>([]);
	const [page, setPage] = useState(1);
	const [total, setTotal] = useState(0);
	const [loading, setLoading] = useState(true);
	useEffect(() => {
		setLoading(true);
		admin
			.auditLogs(page)
			.then((d) => {
				setLogs(d.logs);
				setTotal(d.total);
			})
			.finally(() => setLoading(false));
	}, [page]);

	const totalPages = Math.max(1, Math.ceil(total / 30));
	if (loading) return <Loader />;
	return (
		<div>
			<div className="space-y-1.5">
				{logs.map((l) => (
					<Card key={l.id} className="flex flex-wrap items-center gap-2 p-3 text-sm sm:flex-nowrap sm:gap-3">
						<code className="rounded bg-surface-raised px-2 py-0.5 text-xs text-accent">{l.action}</code>
						<span className="min-w-0 flex-1 truncate text-muted">
							{l.actor ? `@${l.actor.username}` : "system"}
							{l.target_type && ` → ${l.target_type}:${l.target_id}`}
							{l.detail && ` · ${l.detail}`}
						</span>
						<span className="w-full text-xs text-faint sm:w-auto sm:shrink-0">{relativeTime(l.created_at)}</span>
					</Card>
				))}
			</div>
			{totalPages > 1 && (
				<div className="mt-4 flex items-center justify-center gap-3">
					<Button variant="secondary" disabled={page <= 1} onClick={() => setPage((p) => p - 1)}>
						Previous
					</Button>
					<span className="text-sm text-muted">
						Page {page} of {totalPages}
					</span>
					<Button variant="secondary" disabled={page >= totalPages} onClick={() => setPage((p) => p + 1)}>
						Next
					</Button>
				</div>
			)}
		</div>
	);
}

function Loader() {
	return (
		<div className="flex justify-center py-16 text-primary">
			<Spinner className="h-6 w-6" />
		</div>
	);
}
