import { useState } from "react";
import { useMutation, useQueryClient, useSuspenseQuery } from "@tanstack/react-query";
import {
	blocklistsQuery,
	groupCreateMutation,
	groupDeleteMutation,
	groupsQuery,
	groupUpdateMutation,
} from "@/lib/queries";
import type { Blocklist, Group } from "@/lib/types";
import GroupSourcesEditor from "./GroupSourcesEditor";
import InlineError from "@/lib/InlineError";
import { focusRing, primaryButtonClass, smallButtonClass, smallInputClass } from "@/ui/classes";
import { DEFAULT_GROUP_ID } from "@/lib/defaultGroup";

const DEFAULT_GROUP_NOTE = "The default group cannot be renamed or deleted.";

const groupButtonClass = `${smallButtonClass} disabled:opacity-50`;

export default function GroupsPage() {
	const { data: groups } = useSuspenseQuery(groupsQuery());
	const { data: blocklists } = useSuspenseQuery(blocklistsQuery());
	const queryClient = useQueryClient();
	const createMutation = useMutation(groupCreateMutation(queryClient));
	const [newName, setNewName] = useState("");

	return (
		<section>
			<h1 className="text-2xl font-semibold">Groups</h1>
			<form
				className="mt-4 flex flex-wrap items-center gap-2"
				onSubmit={(event) => {
					event.preventDefault();
					const name = newName.trim();
					if (name === "") return;
					createMutation.mutate({ name }, { onSuccess: () => setNewName("") });
				}}
			>
				<label className="text-sm font-medium" htmlFor="new-group-name">
					New group
				</label>
				<input
					id="new-group-name"
					type="text"
					value={newName}
					onChange={(event) => setNewName(event.target.value)}
					className={smallInputClass}
				/>
				<button type="submit" disabled={createMutation.isPending} className={primaryButtonClass}>
					Create
				</button>
			</form>
			<InlineError error={createMutation.error} />
			<ul className="mt-6 space-y-4">
				{groups.map((group) => (
					<GroupRow key={group.id} group={group} blocklists={blocklists} />
				))}
			</ul>
		</section>
	);
}

function GroupRow({ group, blocklists }: { group: Group; blocklists: Blocklist[] }) {
	const queryClient = useQueryClient();
	const updateMutation = useMutation(groupUpdateMutation(queryClient));
	const deleteMutation = useMutation(groupDeleteMutation(queryClient));
	const [renaming, setRenaming] = useState(false);
	const [name, setName] = useState(group.name);
	const [confirming, setConfirming] = useState(false);
	const [expanded, setExpanded] = useState(false);
	const isDefault = group.id === DEFAULT_GROUP_ID;

	return (
		<li className="rounded border border-zinc-200 p-4 dark:border-zinc-700">
			<div className="flex flex-wrap items-center gap-3">
				{renaming ? (
					<form
						className="flex items-center gap-2"
						onSubmit={(event) => {
							event.preventDefault();
							const trimmed = name.trim();
							if (trimmed === "") return;
							updateMutation.mutate(
								{ id: group.id, input: { name: trimmed, safe_search: group.safe_search } },
								{ onSuccess: () => setRenaming(false) },
							);
						}}
					>
						<input
							type="text"
							aria-label={`New name for ${group.name}`}
							value={name}
							onChange={(event) => setName(event.target.value)}
							className={smallInputClass}
							autoFocus
						/>
						<button type="submit" disabled={updateMutation.isPending} className={groupButtonClass}>
							Save
						</button>
						<button
							type="button"
							onClick={() => {
								setName(group.name);
								setRenaming(false);
							}}
							className={groupButtonClass}
						>
							Cancel
						</button>
					</form>
				) : (
					<span className="font-medium">{group.name}</span>
				)}
				<label className="inline-flex items-center gap-2 text-sm">
					<input
						type="checkbox"
						checked={group.safe_search}
						disabled={updateMutation.isPending}
						className={focusRing}
						onChange={(event) =>
							updateMutation.mutate({
								id: group.id,
								input: { name: group.name, safe_search: event.target.checked },
							})
						}
					/>
					Safe search
				</label>
				<span className="ml-auto inline-flex flex-wrap items-center gap-2">
					<button
						type="button"
						aria-expanded={expanded}
						onClick={() => setExpanded((open) => !open)}
						className={groupButtonClass}
					>
						Sources
					</button>
					{!renaming && (
						<button
							type="button"
							disabled={isDefault}
							title={isDefault ? DEFAULT_GROUP_NOTE : undefined}
							onClick={() => {
								setName(group.name);
								setRenaming(true);
							}}
							className={groupButtonClass}
						>
							Rename
						</button>
					)}
					{confirming ? (
						<>
							<button
								type="button"
								onClick={() => {
									setConfirming(false);
									deleteMutation.mutate(group.id);
								}}
								className={`${groupButtonClass} text-red-700 dark:text-red-400`}
							>
								Confirm delete
							</button>
							<button type="button" onClick={() => setConfirming(false)} className={groupButtonClass}>
								Cancel
							</button>
						</>
					) : (
						<button
							type="button"
							disabled={isDefault}
							title={isDefault ? DEFAULT_GROUP_NOTE : undefined}
							onClick={() => setConfirming(true)}
							className={`${groupButtonClass} text-red-700 dark:text-red-400`}
						>
							Delete
						</button>
					)}
				</span>
			</div>
			{isDefault && <p className="mt-2 text-xs text-zinc-500">{DEFAULT_GROUP_NOTE}</p>}
			<InlineError error={updateMutation.error ?? deleteMutation.error} />
			{expanded && <GroupSourcesEditor groupId={group.id} blocklists={blocklists} />}
		</li>
	);
}
