import { useState, type FormEvent } from "react";
import InlineError from "@/lib/InlineError";
import type { Upstream, UpstreamInput } from "@/lib/types";
import { buttonClass, focusRing, inputClass, primaryButtonClass } from "@/ui/classes";

const DEFAULT_PRIORITY = "100";

interface UpstreamFormProps {
	initial?: Upstream;
	busy: boolean;
	error: Error | null;
	onSubmit: (input: UpstreamInput) => Promise<void>;
	onCancel?: () => void;
}

export default function UpstreamForm({ initial, busy, error, onSubmit, onCancel }: UpstreamFormProps) {
	const [url, setUrl] = useState(initial?.url ?? "");
	const [priority, setPriority] = useState(initial === undefined ? DEFAULT_PRIORITY : String(initial.priority));
	const [enabled, setEnabled] = useState(initial?.enabled ?? true);
	const [tlsName, setTlsName] = useState(initial?.tls_name ?? "");

	async function handleSubmit(event: FormEvent<HTMLFormElement>) {
		event.preventDefault();
		const parsed = Number(priority);
		try {
			// PUT replaces the row, so every field goes on every submit.
			await onSubmit({
				url: url.trim(),
				priority: Number.isFinite(parsed) ? parsed : 0,
				enabled,
				tls_name: tlsName.trim(),
			});
			if (initial === undefined) {
				setUrl("");
				setPriority(DEFAULT_PRIORITY);
				setEnabled(true);
				setTlsName("");
			}
		} catch {
			// The page renders the mutation error inline below the form.
		}
	}

	return (
		<form onSubmit={handleSubmit} className="mt-4 max-w-xl space-y-3">
			<h2 className="text-lg font-medium">{initial === undefined ? "Add upstream" : `Edit ${initial.url}`}</h2>
			<div>
				<label htmlFor="upstream-url" className="block text-sm font-medium">
					URL
				</label>
				<input
					id="upstream-url"
					type="text"
					required
					value={url}
					onChange={(event) => setUrl(event.target.value)}
					placeholder="udp://1.1.1.1:53"
					className={inputClass}
				/>
			</div>
			<div>
				<label htmlFor="upstream-priority" className="block text-sm font-medium">
					Priority
				</label>
				<input
					id="upstream-priority"
					type="number"
					min={0}
					value={priority}
					onChange={(event) => setPriority(event.target.value)}
					className={inputClass}
				/>
			</div>
			<div>
				<label htmlFor="upstream-tls-name" className="block text-sm font-medium">
					TLS name
				</label>
				<input
					id="upstream-tls-name"
					type="text"
					value={tlsName}
					onChange={(event) => setTlsName(event.target.value)}
					placeholder="one.one.one.one"
					className={inputClass}
				/>
				<p className="mt-1 text-xs text-zinc-500">
					The SNI and certificate name for a <code>tls://</code> upstream. Leave empty for every other scheme.
				</p>
			</div>
			<label className="flex items-center gap-2 text-sm font-medium">
				<input
					type="checkbox"
					checked={enabled}
					onChange={(event) => setEnabled(event.target.checked)}
					className={focusRing}
				/>
				Enabled
			</label>
			<div className="flex items-center gap-2">
				<button type="submit" disabled={busy} className={primaryButtonClass}>
					{initial === undefined ? "Add upstream" : "Save changes"}
				</button>
				{onCancel !== undefined && (
					<button type="button" onClick={onCancel} className={`${buttonClass} font-medium`}>
						Cancel
					</button>
				)}
			</div>
			<InlineError error={error} />
		</form>
	);
}
