import { useState, type FormEvent } from "react";
import { useMutation, useQueryClient, useSuspenseQuery } from "@tanstack/react-query";
import { formatTime } from "@/lib/format";
import InlineError from "@/lib/InlineError";
import { groupsQuery, ruleCreateMutation, ruleDeleteMutation, rulesQuery } from "@/lib/queries";
import type { Rule, RuleAction, RuleKind } from "@/lib/types";
import { defaultGroupId } from "@/lib/defaultGroup";
import { dangerLinkButtonClass, inputClass, primaryButtonClass, tableWrapClass, tdClass, thClass } from "@/ui/classes";

export default function RulesPage() {
	const queryClient = useQueryClient();
	const { data: rules } = useSuspenseQuery(rulesQuery());
	const { data: groups } = useSuspenseQuery(groupsQuery());

	const create = useMutation(ruleCreateMutation(queryClient));
	const remove = useMutation(ruleDeleteMutation(queryClient));

	const [pattern, setPattern] = useState("");
	const [kind, setKind] = useState<RuleKind>("exact");
	const [action, setAction] = useState<RuleAction>("block");
	const [groupId, setGroupId] = useState(() => defaultGroupId(groups));

	function onSubmit(event: FormEvent<HTMLFormElement>) {
		event.preventDefault();
		create.mutate(
			{ group_id: groupId, pattern: pattern.trim(), kind, action },
			{ onSuccess: () => setPattern("") },
		);
	}

	function deleteRule(rule: Rule) {
		if (window.confirm(`Delete the ${rule.action} rule for "${rule.pattern}"?`)) {
			remove.mutate(rule.id);
		}
	}

	return (
		<section>
			<h1 className="text-2xl font-semibold">Rules</h1>

			{rules.length === 0 ? (
				<p className="mt-4 text-zinc-500">No allow or block rules yet. Create one below.</p>
			) : (
				<div className={tableWrapClass}>
					<table className="w-full min-w-max border-collapse text-sm">
						<thead>
							<tr>
								<th className={thClass}>Pattern</th>
								<th className={thClass}>Kind</th>
								<th className={thClass}>Action</th>
								<th className={thClass}>Group</th>
								<th className={thClass}>Created</th>
								<th className={thClass}>
									<span className="sr-only">Actions</span>
								</th>
							</tr>
						</thead>
						<tbody>
							{rules.map((rule) => (
								<tr key={rule.id}>
									<td className={`${tdClass} font-medium`}>{rule.pattern}</td>
									<td className={tdClass}>{rule.kind}</td>
									<td className={tdClass}>
										<span
											className={
												rule.action === "allow"
													? "text-green-700 dark:text-green-400"
													: "text-red-600 dark:text-red-400"
											}
										>
											{rule.action}
										</span>
									</td>
									<td className={tdClass}>{rule.group}</td>
									<td className={tdClass}>{formatTime(rule.created_at)}</td>
									<td className={tdClass}>
										<button
											type="button"
											onClick={() => deleteRule(rule)}
											disabled={remove.isPending}
											className={dangerLinkButtonClass}
										>
											Delete
										</button>
									</td>
								</tr>
							))}
						</tbody>
					</table>
				</div>
			)}
			<InlineError error={remove.error} />

			<form onSubmit={onSubmit} className="mt-6 max-w-xl space-y-3">
				<h2 className="text-lg font-medium">Create rule</h2>
				<div>
					<label htmlFor="rule-pattern" className="block text-sm font-medium">
						Pattern
					</label>
					<input
						id="rule-pattern"
						type="text"
						required
						value={pattern}
						onChange={(event) => setPattern(event.target.value)}
						placeholder="ads.example.com or *.example.com"
						className={inputClass}
					/>
				</div>
				<div className="grid grid-cols-1 gap-3 sm:grid-cols-3">
					<div>
						<label htmlFor="rule-kind" className="block text-sm font-medium">
							Kind
						</label>
						<select
							id="rule-kind"
							value={kind}
							onChange={(event) => setKind(event.target.value as RuleKind)}
							className={inputClass}
						>
							<option value="exact">exact</option>
							<option value="wildcard">wildcard</option>
						</select>
					</div>
					<div>
						<label htmlFor="rule-action" className="block text-sm font-medium">
							Action
						</label>
						<select
							id="rule-action"
							value={action}
							onChange={(event) => setAction(event.target.value as RuleAction)}
							className={inputClass}
						>
							<option value="allow">allow</option>
							<option value="block">block</option>
						</select>
					</div>
					<div>
						<label htmlFor="rule-group" className="block text-sm font-medium">
							Group
						</label>
						<select
							id="rule-group"
							value={groupId}
							onChange={(event) => setGroupId(Number(event.target.value))}
							className={inputClass}
						>
							{groups.map((group) => (
								<option key={group.id} value={group.id}>
									{group.name}
								</option>
							))}
						</select>
					</div>
				</div>
				<button type="submit" disabled={create.isPending} className={primaryButtonClass}>
					{create.isPending ? "Creating…" : "Create rule"}
				</button>
				<InlineError error={create.error} />
			</form>
		</section>
	);
}
