import { useState, type FormEvent } from "react";
import * as stylex from "@stylexjs/stylex";
import InlineError from "@/lib/InlineError";
import type { Upstream, UpstreamInput } from "@/lib/types";
import { styles as shared } from "@/ui/styles";
import { colors } from "@/ui/tokens.stylex";

const DEFAULT_PRIORITY = "100";

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

const styles = stylex.create({
	form: {
		display: "flex",
		flexDirection: "column",
		gap: "0.75rem",
		marginTop: "1rem",
		maxWidth: "36rem",
	},
	heading: {
		fontSize: "1.125rem",
		lineHeight: "1.75rem",
		fontWeight: 500,
	},
	fieldLabel: {
		display: "block",
		fontSize: "0.875rem",
		lineHeight: "1.25rem",
		fontWeight: 500,
	},
	hint: {
		marginTop: "0.25rem",
		fontSize: "0.75rem",
		lineHeight: "1rem",
		color: colors.textMuted,
	},
	checkboxLabel: {
		display: "flex",
		alignItems: "center",
		gap: "0.5rem",
		fontSize: "0.875rem",
		lineHeight: "1.25rem",
		fontWeight: 500,
	},
	actions: {
		display: "flex",
		alignItems: "center",
		gap: "0.5rem",
	},
	cancelButton: {
		fontWeight: 500,
	},
});

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} {...stylex.props(styles.form)}>
			<h2 {...stylex.props(styles.heading)}>{initial === undefined ? "Add upstream" : `Edit ${initial.url}`}</h2>
			<div>
				<label htmlFor="upstream-url" {...stylex.props(styles.fieldLabel)}>
					URL
				</label>
				<input
					id="upstream-url"
					type="text"
					required
					value={url}
					onChange={(event) => setUrl(event.target.value)}
					placeholder="udp://1.1.1.1:53"
					{...stylex.props(shared.input, shared.focusRing)}
				/>
			</div>
			<div>
				<label htmlFor="upstream-priority" {...stylex.props(styles.fieldLabel)}>
					Priority
				</label>
				<input
					id="upstream-priority"
					type="number"
					min={0}
					value={priority}
					onChange={(event) => setPriority(event.target.value)}
					{...stylex.props(shared.input, shared.focusRing)}
				/>
			</div>
			<div>
				<label htmlFor="upstream-tls-name" {...stylex.props(styles.fieldLabel)}>
					TLS name
				</label>
				<input
					id="upstream-tls-name"
					type="text"
					value={tlsName}
					onChange={(event) => setTlsName(event.target.value)}
					placeholder="one.one.one.one"
					{...stylex.props(shared.input, shared.focusRing)}
				/>
				<p {...stylex.props(styles.hint)}>
					The SNI and certificate name for a <code>tls://</code> upstream. Leave empty for every other scheme.
				</p>
			</div>
			<label {...stylex.props(styles.checkboxLabel)}>
				<input
					type="checkbox"
					checked={enabled}
					onChange={(event) => setEnabled(event.target.checked)}
					{...stylex.props(shared.focusRing)}
				/>
				Enabled
			</label>
			<div {...stylex.props(styles.actions)}>
				<button type="submit" disabled={busy} {...stylex.props(shared.primaryButton, shared.focusRing)}>
					{initial === undefined ? "Add upstream" : "Save changes"}
				</button>
				{onCancel !== undefined && (
					<button
						type="button"
						onClick={onCancel}
						{...stylex.props(shared.button, styles.cancelButton, shared.focusRing)}
					>
						Cancel
					</button>
				)}
			</div>
			<InlineError error={error} />
		</form>
	);
}
