"use client";

import React from "react";
import {
	Check,
	Copy,
	Eye,
	EyeOff,
	KeyRound,
	Loader2,
} from "lucide-react";

import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import {
	Tooltip,
	TooltipContent,
	TooltipTrigger,
} from "@/components/ui/tooltip";

import {
	adminResetUserPassword,
	ApiClientError,
} from "@/lib/frontend/apiClient";
import { buildLoginUrl, LOGIN_REASONS } from "@/lib/frontend/authRedirect";
import {
	getDisplayedTemporaryPassword,
	hasTemporaryPassword,
} from "@/lib/frontend/admin/users/userManagementUx";
import {
	notifySuccess,
	notifyError,
	notifyApiError,
} from "@/lib/frontend/ui/toast";
import { writeTextToClipboard } from "@/lib/frontend/ui/clipboard";

function useCopySuccessTimeout(isActive, onReset) {
	React.useEffect(() => {
		if (!isActive) return undefined;
		const timer = window.setTimeout(() => onReset?.(), 1200);
		return () => window.clearTimeout(timer);
	}, [isActive, onReset]);
}

export default function UserTemporaryPasswordField({
	user,
	temporaryPassword,
	onTemporaryPasswordChange,
	onPasswordReset,
	disabled = false,
	compact = false,
}) {
	const [isVisible, setIsVisible] = React.useState(false);
	const [isResetting, setIsResetting] = React.useState(false);
	const [copySuccess, setCopySuccess] = React.useState(false);

	const hasTempPassword = hasTemporaryPassword(temporaryPassword);
	const isDisabled = Boolean(disabled || isResetting || !user?.id);

	useCopySuccessTimeout(copySuccess, () => setCopySuccess(false));

	React.useEffect(() => {
		if (hasTempPassword) return;
		setIsVisible(false);
		setCopySuccess(false);
	}, [hasTempPassword]);

	const redirectToLoginExpired = React.useCallback(() => {
		const next =
			typeof window !== "undefined"
				? `${window.location.pathname}${window.location.search}`
				: "/admin/users";

		window.location.replace(
			buildLoginUrl({ reason: LOGIN_REASONS.EXPIRED, next }),
		);
	}, []);

	const handleResetPassword = React.useCallback(async () => {
		if (!user?.id || isDisabled) return;

		setIsResetting(true);
		setCopySuccess(false);

		try {
			const result = await adminResetUserPassword(String(user.id));
			const nextPassword =
				typeof result?.temporaryPassword === "string"
					? result.temporaryPassword
					: "";

			if (!nextPassword) {
				throw new Error("Missing temporaryPassword in reset response");
			}

			onTemporaryPasswordChange?.(nextPassword);
			setIsVisible(false);

			notifySuccess({
				title: "Temporäres Passwort gesetzt",
				description: `Für "${user.username}" wurde ein neues Startpasswort erstellt.`,
			});

			onPasswordReset?.();
		} catch (err) {
			if (err instanceof ApiClientError) {
				if (err.code === "AUTH_UNAUTHENTICATED") {
					notifyApiError(err);
					redirectToLoginExpired();
					return;
				}

				if (
					err.code === "VALIDATION_INVALID_FIELD" &&
					err.details?.reason === "SELF_PASSWORD_RESET_FORBIDDEN"
				) {
					notifyError({
						title: "Nicht möglich",
						description:
							"Sie können Ihr eigenes Passwort hier nicht zurücksetzen.",
					});
					return;
				}

				if (err.code === "USER_NOT_FOUND") {
					notifyError({
						title: "Benutzer nicht gefunden.",
						description:
							"Der Benutzer existiert nicht (mehr). Bitte aktualisieren Sie die Liste.",
					});
					return;
				}

				notifyApiError(err, {
					fallbackTitle: "Passwort konnte nicht zurückgesetzt werden.",
					fallbackDescription: "Bitte versuchen Sie es erneut.",
				});
				return;
			}

			notifyError({
				title: "Passwort konnte nicht zurückgesetzt werden.",
				description: "Bitte versuchen Sie es erneut.",
			});
		} finally {
			setIsResetting(false);
		}
	}, [
		user?.id,
		user?.username,
		isDisabled,
		onTemporaryPasswordChange,
		onPasswordReset,
		redirectToLoginExpired,
	]);

	const handleToggleVisible = React.useCallback(() => {
		if (!hasTempPassword || isDisabled) return;
		setIsVisible((prev) => !prev);
	}, [hasTempPassword, isDisabled]);

	const handleCopyPassword = React.useCallback(async () => {
		if (!hasTempPassword || isDisabled) return;

		const result = await writeTextToClipboard(temporaryPassword);
		if (result.ok) {
			setCopySuccess(true);
			return;
		}

		notifyError({
			title: "Kopieren nicht verfügbar",
			description: "Die Zwischenablage ist in diesem Browser nicht verfügbar.",
		});
	}, [hasTempPassword, isDisabled, temporaryPassword]);

	const displayValue = getDisplayedTemporaryPassword({
		temporaryPassword,
		isVisible,
	});

	const controls = (
		<div className="flex items-center gap-1">
			<Tooltip>
				<TooltipTrigger asChild>
					<Button
						type="button"
						variant="outline"
						size="icon-sm"
						disabled={isDisabled}
						onClick={handleResetPassword}
						title="Temporäres Passwort setzen"
						aria-label="Temporäres Passwort setzen"
					>
						{isResetting ? (
							<Loader2 className="h-4 w-4 animate-spin" />
						) : (
							<KeyRound className="h-4 w-4" />
						)}
					</Button>
				</TooltipTrigger>
				<TooltipContent sideOffset={6}>
					Temporäres Passwort setzen
				</TooltipContent>
			</Tooltip>

			<Tooltip>
				<TooltipTrigger asChild>
					<Button
						type="button"
						variant="outline"
						size="icon-sm"
						disabled={isDisabled || !hasTempPassword}
						onClick={handleToggleVisible}
						title={isVisible ? "Passwort verbergen" : "Passwort anzeigen"}
						aria-label={isVisible ? "Passwort verbergen" : "Passwort anzeigen"}
					>
						{isVisible ? (
							<EyeOff className="h-4 w-4" />
						) : (
							<Eye className="h-4 w-4" />
						)}
					</Button>
				</TooltipTrigger>
				<TooltipContent sideOffset={6}>
					{isVisible ? "Passwort verbergen" : "Passwort anzeigen"}
				</TooltipContent>
			</Tooltip>

			<Tooltip>
				<TooltipTrigger asChild>
					<Button
						type="button"
						variant="outline"
						size="icon-sm"
						disabled={isDisabled || !hasTempPassword}
						onClick={handleCopyPassword}
						title="Passwort kopieren"
						aria-label="Passwort kopieren"
					>
						{copySuccess ? (
							<Check className="h-4 w-4 text-emerald-600 dark:text-emerald-400" />
						) : (
							<Copy className="h-4 w-4" />
						)}
					</Button>
				</TooltipTrigger>
				<TooltipContent sideOffset={6}>Passwort kopieren</TooltipContent>
			</Tooltip>
		</div>
	);

	if (compact) {
		return (
			<div className="flex items-center justify-between gap-2">
				<span className="truncate font-mono text-xs tracking-wide text-foreground">
					{displayValue}
				</span>
				{controls}
			</div>
		);
	}

	return (
		<div className="grid gap-2">
			<div className="flex items-center gap-2">
				<Input
					value={displayValue}
					readOnly
					disabled
					className="font-mono tracking-wide"
				/>
				{controls}
			</div>
			<p className="text-xs text-muted-foreground">
				{hasTempPassword
					? "Das temporäre Passwort ist nur in dieser Ansicht verfügbar."
					: "Noch kein temporäres Passwort gesetzt. Bitte zuerst zurücksetzen."}
			</p>
		</div>
	);
}
