import { useWatch, type UseFormReturn } from "react-hook-form";
import { FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from "~/client/components/ui/form";
import { Input } from "~/client/components/ui/input";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "~/client/components/ui/select";
import { Checkbox } from "~/client/components/ui/checkbox";
import { Textarea } from "~/client/components/ui/textarea";
import { WebhookRequestPreview } from "~/client/components/webhook-request-preview";
import type { NotificationFormValues } from "../create-notification-form";

type Props = {
	form: UseFormReturn<NotificationFormValues>;
};

const WebhookPreview = ({ values }: { values: Partial<NotificationFormValues> }) => {
	if (values.type !== "generic") return null;

	const contentType = values.contentType || "application/json";
	const headers = values.headers?.filter(Boolean) || [];
	const useJson = values.useJson;
	const titleKey = values.titleKey || "title";
	const messageKey = values.messageKey || "message";

	let body = "";
	if (useJson) {
		body = JSON.stringify(
			{
				[titleKey]: "Notification title",
				[messageKey]: "Notification message",
			},
			null,
			2,
		);
	} else {
		body = "Notification message";
	}

	return (
		<WebhookRequestPreview
			method={values.method || "POST"}
			url={values.url}
			contentType={contentType}
			headers={headers}
			body={body}
		/>
	);
};

export const GenericForm = ({ form }: Props) => {
	const watchedValues = useWatch({ control: form.control });
	const useJson = useWatch({ control: form.control, name: "useJson" });

	return (
		<>
			<FormField
				control={form.control}
				name="url"
				render={({ field }) => (
					<FormItem>
						<FormLabel>Webhook URL</FormLabel>
						<FormControl>
							<Input {...field} placeholder="https://api.example.com/webhook" />
						</FormControl>
						<FormDescription>The target origin must be listed in WEBHOOK_ALLOWED_ORIGINS.</FormDescription>
						<FormMessage />
					</FormItem>
				)}
			/>
			<FormField
				control={form.control}
				name="method"
				render={({ field }) => (
					<FormItem>
						<FormLabel>Method</FormLabel>
						<Select onValueChange={field.onChange} value={field.value ?? ""}>
							<FormControl>
								<SelectTrigger>
									<SelectValue placeholder="Select method" />
								</SelectTrigger>
							</FormControl>
							<SelectContent>
								<SelectItem value="GET">GET</SelectItem>
								<SelectItem value="POST">POST</SelectItem>
							</SelectContent>
						</Select>
						<FormMessage />
					</FormItem>
				)}
			/>
			<FormField
				control={form.control}
				name="contentType"
				render={({ field }) => (
					<FormItem>
						<FormLabel>Content Type</FormLabel>
						<FormControl>
							<Input {...field} placeholder="application/json" />
						</FormControl>
						<FormMessage />
					</FormItem>
				)}
			/>
			<FormField
				control={form.control}
				name="headers"
				render={({ field }) => (
					<FormItem>
						<FormLabel>Headers</FormLabel>
						<FormControl>
							<Textarea
								{...field}
								placeholder="Authorization: Bearer token&#10;X-Custom-Header: value"
								value={Array.isArray(field.value) ? field.value.join("\n") : ""}
								onChange={(e) =>
									field.onChange(
										e.target.value
											.split("\n")
											.map((header) => header.trim())
											.filter(Boolean),
									)
								}
							/>
						</FormControl>
						<FormDescription>
							One header per line in Key: Value format. Values are stored as plain text.
						</FormDescription>
						<FormMessage />
					</FormItem>
				)}
			/>
			<FormField
				control={form.control}
				name="useJson"
				render={({ field }) => (
					<FormItem className="flex flex-row items-center space-x-3">
						<FormControl>
							<Checkbox checked={field.value} onCheckedChange={(checked) => field.onChange(checked)} />
						</FormControl>
						<div className="space-y-1 leading-none">
							<FormLabel>Use JSON Template</FormLabel>
							<FormDescription>Send the message as a JSON object.</FormDescription>
						</div>
					</FormItem>
				)}
			/>
			{useJson && (
				<>
					<FormField
						control={form.control}
						name="titleKey"
						render={({ field }) => (
							<FormItem>
								<FormLabel>Title Key</FormLabel>
								<FormControl>
									<Input {...field} placeholder="title" />
								</FormControl>
								<FormDescription>The JSON key for the notification title.</FormDescription>
								<FormMessage />
							</FormItem>
						)}
					/>
					<FormField
						control={form.control}
						name="messageKey"
						render={({ field }) => (
							<FormItem>
								<FormLabel>Message Key</FormLabel>
								<FormControl>
									<Input {...field} placeholder="message" />
								</FormControl>
								<FormDescription>The JSON key for the notification message.</FormDescription>
								<FormMessage />
							</FormItem>
						)}
					/>
				</>
			)}
			<WebhookPreview values={watchedValues} />
		</>
	);
};
