import { useState } from "react";
import { useMutation, useQueryClient, useSuspenseQuery } from "@tanstack/react-query";
import { clientDeleteMutation, clientPrefixesQuery, clientsQuery, groupsQuery } from "@/lib/queries";
import { formatTime } from "@/lib/format";
import type { Client } from "@/lib/types";
import ClientEditDialog from "./ClientEditDialog";
import PrefixesEditor from "./PrefixesEditor";
import InlineError from "@/lib/InlineError";
import { smallButtonClass, tableWrapClass } from "@/ui/classes";
import { READ_ONLY_HINT, useReadOnlyConfig } from "@/features/settings/authority";

const cellClass = "px-3 py-2";

/**
 * Deleting an observed row discards runtime state the file never declared, so
 * it stays live under file authority; deleting a hand-edited row contradicts
 * the file and is the one client DELETE the server answers 403 (ruling 7).
 */
const DECLARED_CLIENT_NOTE = "This client is declared in the configuration file; remove it there and restart.";

export default function ClientsPage() {
	const { data: clients } = useSuspenseQuery(clientsQuery());
	const { data: prefixes } = useSuspenseQuery(clientPrefixesQuery());
	const { data: groups } = useSuspenseQuery(groupsQuery());
	const queryClient = useQueryClient();
	const deleteMutation = useMutation(clientDeleteMutation(queryClient));
	const [editing, setEditing] = useState<Client | null>(null);
	const [confirmingId, setConfirmingId] = useState<number | null>(null);
	const readOnly = useReadOnlyConfig();

	return (
		<section>
			<h1 className="text-2xl font-semibold">Clients</h1>
			{clients.length === 0 ? (
				<p className="mt-4 text-zinc-500">
					No clients yet. Rows appear automatically as devices on the network make DNS queries — there is
					nothing to create by hand.
				</p>
			) : (
				<div className={tableWrapClass}>
					<table className="w-full min-w-[48rem] text-left text-sm">
						<thead>
							<tr className="border-b border-zinc-200 text-zinc-500 dark:border-zinc-700">
								<th className={cellClass}>IP</th>
								<th className={cellClass}>Name</th>
								<th className={cellClass}>Group</th>
								<th className={cellClass}>First seen</th>
								<th className={cellClass}>Last seen</th>
								<th className={cellClass}>
									<span className="sr-only">Actions</span>
								</th>
							</tr>
						</thead>
						<tbody>
							{clients.map((client) => (
								<tr key={client.id} className="border-b border-zinc-100 dark:border-zinc-800">
									<td className={`${cellClass} font-mono`}>{client.ip}</td>
									<td className={cellClass}>
										{client.name === "" ? <span className="text-zinc-400">—</span> : client.name}
										{client.hand_edited && (
											<span className="ml-2 rounded bg-blue-100 px-1.5 py-0.5 text-xs font-medium text-blue-800 dark:bg-blue-900 dark:text-blue-200">
												edited
											</span>
										)}
									</td>
									<td className={cellClass}>{client.group}</td>
									<td className={cellClass}>{formatTime(client.first_seen)}</td>
									<td className={cellClass}>{formatTime(client.last_seen)}</td>
									<td className={`${cellClass} text-right`}>
										{confirmingId === client.id ? (
											<span className="inline-flex flex-wrap items-center justify-end gap-2">
												<span className="text-xs text-zinc-500">
													Deleted clients re-materialize on their next DNS query.
												</span>
												<button
													type="button"
													onClick={() => {
														setConfirmingId(null);
														deleteMutation.mutate(client.id);
													}}
													className={`${smallButtonClass} text-red-700 dark:text-red-400`}
												>
													Confirm delete
												</button>
												<button
													type="button"
													onClick={() => setConfirmingId(null)}
													className={smallButtonClass}
												>
													Cancel
												</button>
											</span>
										) : (
											<span className="inline-flex gap-2">
												<button
													type="button"
													onClick={() => setEditing(client)}
													disabled={readOnly}
													title={readOnly ? READ_ONLY_HINT : undefined}
													className={`${smallButtonClass} disabled:opacity-50`}
												>
													Edit
												</button>
												<button
													type="button"
													onClick={() => setConfirmingId(client.id)}
													disabled={readOnly && client.hand_edited}
													title={
														readOnly && client.hand_edited
															? DECLARED_CLIENT_NOTE
															: undefined
													}
													className={`${smallButtonClass} text-red-700 disabled:opacity-50 dark:text-red-400`}
												>
													Delete
												</button>
											</span>
										)}
									</td>
								</tr>
							))}
						</tbody>
					</table>
				</div>
			)}
			<InlineError error={deleteMutation.error} />
			{editing !== null && <ClientEditDialog client={editing} groups={groups} onClose={() => setEditing(null)} />}
			<PrefixesEditor prefixes={prefixes} groups={groups} />
		</section>
	);
}
