import { useState, useCallback, useEffect } from "react";
import {
	Card,
	CardContent,
	CardDescription,
	CardHeader,
	CardTitle,
	Input,
	Label,
	Button,
	Alert,
	AlertDescription,
	Badge,
	ScrollArea,
	Loader2,
	CheckCircle2,
	XCircle,
	AlertCircle,
	Eye,
	EyeOff,
	Key,
	Zap,
	Settings,
	Send,
	Copy,
	RefreshCw,
	toast,
	t,
	useAlertDialog,
} from "@block-ninja/ui";

type PluginSettingsProps = {
	pluginName: string;
};

type SettingsData = {
	api_key_configured: boolean;
	api_key_masked?: string;
	webhook_url?: string;
	webhook_secret_configured?: boolean;
	webhook_secret_masked?: string;
	last_event_at?: string;
	last_event_type?: string;
};

type TestResult = {
	success: boolean;
	error?: string;
	event_types?: { id: number; title: string; slug: string }[];
};

const copyToClipboard = async (text: string) => {
	if (!text) return;
	try {
		await navigator.clipboard.writeText(text);
		toast.success(t("calcom.settings.copied", "Copied to clipboard"));
	} catch (_error) {
		// Clipboard API may be unavailable (non-secure context).
		toast.error(t("calcom.settings.copyFailed", "Could not copy to clipboard"));
	}
};

const formatRelativeTime = (iso: string): string => {
	const parsed = Date.parse(iso);
	if (Number.isNaN(parsed)) return iso;
	const diffMs = Date.now() - parsed;
	const minutes = Math.round(diffMs / 60000);
	if (minutes < 1) return t("calcom.settings.relative.justNow", "just now");
	if (minutes < 60) {
		return minutes === 1 ? t("calcom.settings.relative.minute", "1 minute ago") : t("calcom.settings.relative.minutes", "{count} minutes ago").replace("{count}", String(minutes));
	}
	const hours = Math.round(minutes / 60);
	if (hours < 24) {
		return hours === 1 ? t("calcom.settings.relative.hour", "1 hour ago") : t("calcom.settings.relative.hours", "{count} hours ago").replace("{count}", String(hours));
	}
	const days = Math.round(hours / 24);
	return days === 1 ? t("calcom.settings.relative.day", "1 day ago") : t("calcom.settings.relative.days", "{count} days ago").replace("{count}", String(days));
};

function CalcomSettings({ pluginName }: PluginSettingsProps) {
	const { confirm } = useAlertDialog();
	const [apiKey, setApiKey] = useState("");
	const [showApiKey, setShowApiKey] = useState(false);
	const [loading, setLoading] = useState(true);
	const [saving, setSaving] = useState(false);
	const [testing, setTesting] = useState(false);
	const [rotating, setRotating] = useState(false);
	const [showSecret, setShowSecret] = useState(false);
	const [settings, setSettings] = useState<SettingsData | null>(null);
	const [testResult, setTestResult] = useState<TestResult | null>(null);
	const [saveMessage, setSaveMessage] = useState<{ type: "success" | "error"; text: string } | null>(null);

	const baseUrl = `/api/plugins/${pluginName}`;

	// Follow-up: when @block-ninja/ui re-exports useQuery from connect-query
	// AND this plugin's settings endpoints move to proto-backed RPCs, swap this
	// useEffect + fetch pair for useQuery with a staleTime so re-opening the
	// settings panel does not refetch. Today neither precondition holds (no
	// .proto for this plugin, no tanstack-query primitives re-exported), so
	// the raw fetch stays.
	const loadSettings = useCallback(async () => {
		try {
			const res = await fetch(`${baseUrl}/settings`);
			if (res.ok) {
				const data = await res.json();
				setSettings(data);
			}
		} catch (_error) {
			console.error("Failed to load settings");
		} finally {
			setLoading(false);
		}
	}, [baseUrl]);

	useEffect(() => {
		loadSettings();
	}, [loadSettings]);

	// Save API key
	const handleSave = async () => {
		if (!apiKey.trim()) {
			setSaveMessage({ type: "error", text: t("calcom.settings.apiKey.errorEmpty", "Please enter an API key") });
			return;
		}

		setSaving(true);
		setSaveMessage(null);
		setTestResult(null);

		try {
			const res = await fetch(`${baseUrl}/settings`, {
				method: "POST",
				headers: { "Content-Type": "application/json" },
				body: JSON.stringify({ api_key: apiKey }),
			});

			if (res.ok) {
				// Reload settings to pick up the auto-generated webhook secret.
				await loadSettings();
				setApiKey("");
				setSaveMessage({ type: "success", text: t("calcom.settings.apiKey.saved", "API key saved successfully") });
			} else {
				const text = await res.text();
				setSaveMessage({ type: "error", text: text || t("calcom.settings.apiKey.saveFailed", "Failed to save API key") });
			}
		} catch (_error) {
			setSaveMessage({ type: "error", text: t("calcom.settings.serverError", "Failed to connect to server") });
		} finally {
			setSaving(false);
		}
	};

	// Test connection
	const handleTest = async () => {
		setTesting(true);
		setTestResult(null);

		try {
			const res = await fetch(`${baseUrl}/test`, { method: "POST" });
			const data = await res.json();
			setTestResult(data);
		} catch (_error) {
			setTestResult({ success: false, error: t("calcom.settings.serverError", "Failed to connect to server") });
		} finally {
			setTesting(false);
		}
	};

	// Clear API key
	const handleClear = async () => {
		setSaving(true);
		setSaveMessage(null);

		try {
			const res = await fetch(`${baseUrl}/settings`, {
				method: "POST",
				headers: { "Content-Type": "application/json" },
				body: JSON.stringify({ api_key: "" }),
			});

			if (res.ok) {
				await loadSettings();
				setTestResult(null);
				setSaveMessage({ type: "success", text: t("calcom.settings.apiKey.removed", "API key removed") });
			}
		} catch (_error) {
			setSaveMessage({ type: "error", text: t("calcom.settings.apiKey.clearFailed", "Failed to clear API key") });
		} finally {
			setSaving(false);
		}
	};

	// Rotate webhook secret
	const handleRotate = async () => {
		const confirmed = await confirm({
			title: t("calcom.settings.webhook.rotateConfirmTitle", "Rotate webhook secret?"),
			message: t("calcom.settings.webhook.rotateConfirmMessage", "This invalidates the existing secret immediately. You'll need to update Cal.com to keep webhooks flowing."),
			confirmLabel: t("calcom.settings.webhook.rotateConfirmLabel", "Rotate"),
			variant: "destructive",
		});
		if (!confirmed) return;

		setRotating(true);
		setSaveMessage(null);
		try {
			const res = await fetch(`${baseUrl}/settings/rotate-webhook-secret`, { method: "POST" });
			if (res.ok) {
				const data = await res.json();
				setSettings((prev) => (prev ? { ...prev, webhook_secret_masked: data.webhook_secret_masked, webhook_secret_configured: true } : prev));
				const successMsg = t("calcom.settings.webhook.rotated", "Webhook secret rotated. Update it in Cal.com.");
				setSaveMessage({ type: "success", text: successMsg });
				toast.success(successMsg);
			} else {
				setSaveMessage({ type: "error", text: t("calcom.settings.webhook.rotateFailed", "Failed to rotate webhook secret") });
			}
		} catch (_error) {
			setSaveMessage({ type: "error", text: t("calcom.settings.serverError", "Failed to connect to server") });
		} finally {
			setRotating(false);
		}
	};

	if (loading) {
		return (
			<div className="flex items-center justify-center py-8">
				<Loader2 className="h-6 w-6 animate-spin text-muted-foreground" />
			</div>
		);
	}

	const apiKeyVisibilityLabel = showApiKey ? t("calcom.settings.toggleVisibility.hide", "Hide") : t("calcom.settings.toggleVisibility.show", "Show");
	const secretVisibilityLabel = showSecret ? t("calcom.settings.toggleVisibility.hide", "Hide") : t("calcom.settings.toggleVisibility.show", "Show");

	return (
		<div className="space-y-6">
			{/* Header */}
			<div>
				<h2 className="text-xl font-semibold flex items-center gap-2">
					<Settings className="h-5 w-5" />
					{t("calcom.settings.heading", "Cal.com Integration")}
				</h2>
				<p className="text-sm text-muted-foreground">{t("calcom.settings.headingDescription", "Configure your Cal.com API key to enable booking functionality")}</p>
			</div>

			{/* Current Status */}
			<Card>
				<CardHeader>
					<CardTitle className="text-base flex items-center gap-2">
						<Key className="h-4 w-4" />
						{t("calcom.settings.apiKey.title", "API Key Status")}
					</CardTitle>
					<CardDescription>{t("calcom.settings.apiKey.description", "Your Cal.com API key is required for the booking widget to function")}</CardDescription>
				</CardHeader>
				<CardContent className="space-y-4">
					{settings?.api_key_configured ?
						<div className="flex items-center justify-between rounded-lg border bg-muted/30 p-3">
							<div className="flex items-center gap-3">
								<Badge variant="default" className="gap-1.5">
									<CheckCircle2 className="h-3.5 w-3.5" />
									{t("calcom.settings.apiKey.configuredLabel", "Configured")}
								</Badge>
								<p className="text-xs text-muted-foreground font-mono">{settings.api_key_masked || t("calcom.settings.apiKey.maskedFallback", "***configured***")}</p>
							</div>
							<Button action="delete" entity="plugin-setting" variant="ghost" size="sm" onClick={handleClear} disabled={saving}>
								{t("calcom.settings.apiKey.remove", "Remove")}
							</Button>
						</div>
					:	<div className="flex items-center gap-3 rounded-lg border bg-muted/30 p-3">
							<Badge variant="outline" className="gap-1.5">
								<XCircle className="h-3.5 w-3.5" />
								{t("calcom.settings.apiKey.notConfiguredLabel", "Not configured")}
							</Badge>
							<p className="text-xs text-muted-foreground">{t("calcom.settings.apiKey.notConfiguredHelp", "Enter your Cal.com API key below to enable booking")}</p>
						</div>
					}

					{/* API Key Input */}
					<div className="space-y-2">
						<Label htmlFor="apiKey">{settings?.api_key_configured ? t("calcom.settings.apiKey.updateLabel", "Update API Key") : t("calcom.settings.apiKey.label", "API Key")}</Label>
						<div className="flex gap-2">
							<div className="relative flex-1">
								<Input
									id="apiKey"
									type={showApiKey ? "text" : "password"}
									value={apiKey}
									onChange={(e) => setApiKey(e.target.value)}
									placeholder={t("calcom.settings.apiKey.placeholder", "cal_live_...")}
									className="pr-10"
								/>
								<Button
									type="button"
									variant="ghost"
									action="toggle"
									entity="api-key-visibility"
									onClick={() => setShowApiKey(!showApiKey)}
									aria-label={apiKeyVisibilityLabel}
									className="absolute right-3 top-1/2 -translate-y-1/2 h-auto p-0 text-muted-foreground hover:bg-transparent hover:text-foreground">
									{showApiKey ?
										<EyeOff className="h-4 w-4" />
									:	<Eye className="h-4 w-4" />}
								</Button>
							</div>
							<Button action="save" entity="plugin-setting" onClick={handleSave} disabled={saving || !apiKey.trim()}>
								{saving ?
									<Loader2 className="h-4 w-4 animate-spin" />
								:	t("calcom.settings.apiKey.save", "Save")}
							</Button>
						</div>
						<p className="text-xs text-muted-foreground">
							{t("calcom.settings.apiKey.helpPrefix", "Get your API key from")}{" "}
							<a href="https://app.cal.com/settings/developer/api-keys" target="_blank" rel="noopener noreferrer" className="text-primary hover:underline">
								{t("calcom.settings.apiKey.helpLink", "Cal.com API Settings")}
							</a>
						</p>
					</div>

					{/* Save Message */}
					{saveMessage && (
						<Alert variant={saveMessage.type === "error" ? "destructive" : "default"}>
							<AlertDescription>{saveMessage.text}</AlertDescription>
						</Alert>
					)}
				</CardContent>
			</Card>

			{/* Test Connection */}
			{settings?.api_key_configured && (
				<Card>
					<CardHeader>
						<CardTitle className="text-base flex items-center gap-2">
							<Zap className="h-4 w-4" />
							{t("calcom.settings.test.title", "Test Connection")}
						</CardTitle>
						<CardDescription>{t("calcom.settings.test.description", "Verify your API key works and see available event types")}</CardDescription>
					</CardHeader>
					<CardContent className="space-y-4">
						<Button action="settings" entity="plugin-connection" onClick={handleTest} disabled={testing}>
							{testing ?
								<>
									<Loader2 className="mr-2 h-4 w-4 animate-spin" />
									{t("calcom.settings.test.testing", "Testing...")}
								</>
							:	t("calcom.settings.test.button", "Test Connection")}
						</Button>

						{testResult && (
							<div className="space-y-3">
								{testResult.success ?
									<>
										<Alert>
											<CheckCircle2 className="h-4 w-4 text-success" />
											<AlertDescription className="ml-2">
												{t("calcom.settings.test.successPrefix", "Connection successful! Found")} {testResult.event_types?.length || 0}{" "}
												{t("calcom.settings.test.successSuffix", "event types.")}
											</AlertDescription>
										</Alert>

										{testResult.event_types && testResult.event_types.length > 0 && (
											<ScrollArea className="max-h-96 rounded-lg border">
												<table className="w-full text-sm">
													<thead className="bg-muted">
														<tr>
															<th className="text-left px-3 py-2 font-medium">{t("calcom.settings.test.tableEventType", "Event Type")}</th>
															<th className="text-left px-3 py-2 font-medium">{t("calcom.settings.test.tableSlug", "Slug")}</th>
														</tr>
													</thead>
													<tbody>
														{testResult.event_types.map((et) => (
															<tr key={et.id} className="border-t">
																<td className="px-3 py-2">{et.title}</td>
																<td className="px-3 py-2 font-mono text-xs">{et.slug}</td>
															</tr>
														))}
													</tbody>
												</table>
											</ScrollArea>
										)}
									</>
								:	<Alert variant="destructive">
										<XCircle className="h-4 w-4" />
										<AlertDescription className="ml-2">{testResult.error || t("calcom.settings.test.failure", "Connection failed")}</AlertDescription>
									</Alert>
								}
							</div>
						)}
					</CardContent>
				</Card>
			)}

			{/* Webhook */}
			{settings?.api_key_configured && (
				<Card>
					<CardHeader>
						<CardTitle className="text-base flex items-center gap-2">
							<Send className="h-4 w-4" />
							{t("calcom.settings.webhook.title", "Webhook")}
						</CardTitle>
						<CardDescription>{t("calcom.settings.webhook.description", "Configure this URL in Cal.com → Settings → Developer → Webhooks to receive booking events.")}</CardDescription>
					</CardHeader>
					<CardContent className="space-y-4">
						<div className="space-y-2">
							<Label htmlFor="webhookUrl">{t("calcom.settings.webhook.urlLabel", "Webhook URL")}</Label>
							<div className="flex gap-2">
								<Input id="webhookUrl" readOnly value={settings?.webhook_url || ""} className="flex-1 font-mono text-xs" />
								<Button
									action="copy"
									entity="webhook-url"
									variant="outline"
									size="sm"
									aria-label={t("calcom.settings.webhook.copyUrl", "Copy webhook URL")}
									onClick={() => copyToClipboard(settings?.webhook_url || "")}>
									<Copy className="h-4 w-4" />
								</Button>
							</div>
						</div>

						<div className="space-y-2">
							<Label htmlFor="webhookSecret">{t("calcom.settings.webhook.secretLabel", "Webhook Secret")}</Label>
							<div className="flex gap-2">
								<div className="relative flex-1">
									<Input
										id="webhookSecret"
										type={showSecret ? "text" : "password"}
										readOnly
										value={settings?.webhook_secret_masked || t("calcom.settings.webhook.secretNotConfigured", "Not configured")}
										className="pr-10 font-mono text-xs"
									/>
									<Button
										type="button"
										variant="ghost"
										action="toggle"
										entity="webhook-secret-visibility"
										onClick={() => setShowSecret(!showSecret)}
										aria-label={secretVisibilityLabel}
										className="absolute right-3 top-1/2 -translate-y-1/2 h-auto p-0 text-muted-foreground hover:bg-transparent hover:text-foreground">
										{showSecret ?
											<EyeOff className="h-4 w-4" />
										:	<Eye className="h-4 w-4" />}
									</Button>
								</div>
								<Button
									action="copy"
									entity="webhook-secret"
									variant="outline"
									size="sm"
									aria-label={t("calcom.settings.webhook.copySecret", "Copy webhook secret")}
									onClick={() => copyToClipboard(settings?.webhook_secret_masked || "")}>
									<Copy className="h-4 w-4" />
								</Button>
								<Button
									action="rotate"
									entity="webhook-secret"
									variant="outline"
									size="sm"
									aria-label={t("calcom.settings.webhook.rotate", "Rotate webhook secret")}
									onClick={handleRotate}
									disabled={rotating}>
									{rotating ?
										<Loader2 className="h-4 w-4 animate-spin" />
									:	<RefreshCw className="h-4 w-4" />}
								</Button>
							</div>
							<p className="text-xs text-muted-foreground">
								{t(
									"calcom.settings.webhook.secretHelp",
									"Cal.com displays the secret only once. Regenerating invalidates the previous value immediately — update it in Cal.com after rotating.",
								)}
							</p>
						</div>

						<div className="text-sm">
							{settings?.last_event_at ?
								<div className="flex items-center gap-2 text-foreground">
									<CheckCircle2 className="h-4 w-4 text-success" />
									<span>
										{t("calcom.settings.webhook.lastEventPrefix", "Last event")} {formatRelativeTime(settings.last_event_at)}
										{settings.last_event_type && (
											<>
												{" — "}
												<code className="font-mono text-xs">{settings.last_event_type}</code>
											</>
										)}
									</span>
								</div>
							:	<div className="flex items-center gap-2 text-muted-foreground">
									<AlertCircle className="h-4 w-4" />
									<span>{t("calcom.settings.webhook.waitingForEvent", "Status: Waiting for first event")}</span>
								</div>
							}
						</div>
					</CardContent>
				</Card>
			)}

			{/* Documentation */}
			<Card>
				<CardHeader>
					<CardTitle className="text-base">{t("calcom.settings.docs.title", "Documentation")}</CardTitle>
					<CardDescription>{t("calcom.settings.docs.description", "Reference material for working with the Cal.com plugin.")}</CardDescription>
				</CardHeader>
				<CardContent className="space-y-2 text-sm">
					<a href="https://cal.com/docs/api-reference/v2" target="_blank" rel="noopener noreferrer" className="text-primary hover:underline block">
						{t("calcom.settings.docs.calcomApi", "Cal.com API documentation")}
					</a>
					{/* Follow-up: confirm /admin/docs/calcom-plugin route exists; fallback to the FEATURES/docs entry once published. */}
					<a href="/admin/docs/calcom-plugin" target="_blank" rel="noopener noreferrer" className="text-primary hover:underline block">
						{t("calcom.settings.docs.pluginGuide", "BlockNinja plugin guide")}
					</a>
				</CardContent>
			</Card>
		</div>
	);
}

export default CalcomSettings;
