import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
import { useCallback, useEffect, useMemo, useRef, useState, } from "react";
import { Button } from "../../../components/ui/button";
import { Input } from "../../../components/ui/input";
import { clearLicenseCache, formatRetryTimeSimple, requestLicense, storeLicense, verifyActivationCode, } from "../../../licensing/licenseService";
import { setupWizardService } from "../../../setup/services/setupWizardService";
import { SetupStepError } from "../SetupStepError";
import { SetupStepBackButton, SetupStepFooter, SetupStepLayout, } from "../SetupStepLayout";
import { ArrowRight, KeyRound, RefreshCw } from "lucide-react";
function getErrorMessage(error, fallback) {
    return error instanceof Error ? error.message : fallback;
}
export function LicenseActivationStep({ email, mode, onBack, onActivated, onSkip, skipLabel = "Skip", }) {
    const [name, setName] = useState("");
    const [companyName, setCompanyName] = useState("");
    const [codeDigits, setCodeDigits] = useState(["", "", "", "", "", ""]);
    const codeInputRefs = useRef([]);
    const [loading, setLoading] = useState(false);
    const [resending, setResending] = useState(false);
    const [resendMessage, setResendMessage] = useState(null);
    const [error, setError] = useState(null);
    const [retryAfterSeconds, setRetryAfterSeconds] = useState(null);
    const [resendRetryAfterSeconds, setResendRetryAfterSeconds] = useState(null);
    const isTrialFlow = useMemo(() => mode === "trial_form", [mode]);
    const trialFormComplete = useMemo(() => name.trim().length > 0 && companyName.trim().length > 0, [name, companyName]);
    const codeComplete = useMemo(() => codeDigits.every((d) => d.length === 1) &&
        codeDigits.join("").length === 6, [codeDigits]);
    useEffect(() => {
        if (!isTrialFlow) {
            codeInputRefs.current[0]?.focus();
        }
    }, [isTrialFlow]);
    useEffect(() => {
        if (retryAfterSeconds === null || retryAfterSeconds <= 0) {
            return;
        }
        const updateInterval = retryAfterSeconds > 60 ? 60000 : 1000;
        const timer = setInterval(() => {
            setRetryAfterSeconds((prev) => {
                if (prev === null)
                    return null;
                const next = prev - (updateInterval === 60000 ? 60 : 1);
                return next > 0 ? next : 0;
            });
        }, updateInterval);
        return () => clearInterval(timer);
    }, [retryAfterSeconds]);
    useEffect(() => {
        if (resendRetryAfterSeconds === null || resendRetryAfterSeconds <= 0) {
            return;
        }
        const updateInterval = resendRetryAfterSeconds > 60 ? 60000 : 1000;
        const timer = setInterval(() => {
            setResendRetryAfterSeconds((prev) => {
                if (prev === null)
                    return null;
                const next = prev - (updateInterval === 60000 ? 60 : 1);
                return next > 0 ? next : 0;
            });
        }, updateInterval);
        return () => clearInterval(timer);
    }, [resendRetryAfterSeconds]);
    const isRetryLocked = retryAfterSeconds !== null && retryAfterSeconds > 0;
    const isResendRetryLocked = resendRetryAfterSeconds !== null && resendRetryAfterSeconds > 0;
    const handleSkip = onSkip ?? onActivated;
    const handleStoreLicense = useCallback(async (license, v2OuterSignature) => {
        const settingsExist = await setupWizardService.getSettingsExists();
        if (!settingsExist) {
            await setupWizardService.createSettingsItem();
        }
        const result = await storeLicense(license, v2OuterSignature);
        if (!result.success) {
            throw new Error(result.message || "Failed to store license.");
        }
        try {
            await clearLicenseCache();
        }
        catch {
            // Non-fatal cache clear; backend will refresh eventually.
        }
    }, []);
    const completePurchasedActivation = useCallback(async (fullCode) => {
        try {
            setLoading(true);
            setError(null);
            setRetryAfterSeconds(null);
            const response = await verifyActivationCode({ email, code: fullCode });
            if (response.status === "rate_limited") {
                setRetryAfterSeconds(response.retryAfterSeconds || 60);
                throw new Error(response.message ||
                    `Too many incorrect activation code attempts. Try again in ${formatRetryTimeSimple(response.retryAfterSeconds || 60)}.`);
            }
            if (response.status !== "purchased" || !response.license) {
                setRetryAfterSeconds(null);
                throw new Error(response.message || "Activation code is invalid.");
            }
            await handleStoreLicense(response.license, response.signature);
            setRetryAfterSeconds(null);
            onActivated();
        }
        catch (e) {
            setError(getErrorMessage(e, "License activation failed."));
        }
        finally {
            setLoading(false);
        }
    }, [email, handleStoreLicense, onActivated]);
    const handleActivate = useCallback(async () => {
        if (!isTrialFlow && isRetryLocked) {
            return;
        }
        if (isTrialFlow) {
            try {
                setLoading(true);
                setError(null);
                setRetryAfterSeconds(null);
                if (!name.trim() || !companyName.trim()) {
                    setError("Please provide your name and company name.");
                    return;
                }
                const response = await requestLicense({
                    email,
                    name: name.trim(),
                    companyName: companyName.trim(),
                });
                if (response.status !== "trial" || !response.license) {
                    throw new Error(response.message || "Trial activation failed.");
                }
                await handleStoreLicense(response.license, response.signature);
                onActivated();
            }
            catch (e) {
                setError(getErrorMessage(e, "License activation failed."));
            }
            finally {
                setLoading(false);
            }
            return;
        }
        const code = codeDigits.join("");
        if (code.length !== 6) {
            setError("Please enter the activation code.");
            return;
        }
        await completePurchasedActivation(code);
    }, [
        isTrialFlow,
        name,
        companyName,
        email,
        codeDigits,
        handleStoreLicense,
        onActivated,
        completePurchasedActivation,
        isRetryLocked,
    ]);
    const handleResendCode = useCallback(async () => {
        if (isTrialFlow || resending || isResendRetryLocked) {
            return;
        }
        try {
            setResending(true);
            setError(null);
            setResendMessage(null);
            const response = await requestLicense({
                email,
                name: "Setup",
                companyName: "Setup",
            });
            if (response.status === "code_sent") {
                setResendRetryAfterSeconds(null);
                setCodeDigits(["", "", "", "", "", ""]);
                setResendMessage("Code resent");
                queueMicrotask(() => codeInputRefs.current[0]?.focus());
                return;
            }
            if (response.status === "rate_limited") {
                const retrySeconds = response.retryAfterSeconds || 60;
                setResendRetryAfterSeconds(retrySeconds);
                setError(`Too many requests for sending a new code. If you already have a code, enter it now. Otherwise try again in ${formatRetryTimeSimple(retrySeconds)}.`);
                return;
            }
            if (response.status === "trial_expired") {
                setResendRetryAfterSeconds(null);
                setError(response.message ||
                    "Trial period expired for this email. Use activation code flow.");
                return;
            }
            setResendRetryAfterSeconds(null);
            setError(response.message || "Failed to resend activation code.");
        }
        catch (e) {
            setResendRetryAfterSeconds(null);
            setError(getErrorMessage(e, "Failed to contact license service."));
        }
        finally {
            setResending(false);
        }
    }, [email, isResendRetryLocked, isTrialFlow, resending]);
    const handleCodeDigitChange = (index, value) => {
        if (isRetryLocked)
            return;
        const digit = value.replace(/\D/g, "").slice(-1);
        setError(null);
        setResendMessage(null);
        setCodeDigits((prev) => {
            const next = [...prev];
            next[index] = digit;
            if (digit && index < 5) {
                queueMicrotask(() => codeInputRefs.current[index + 1]?.focus());
            }
            const full = next.join("");
            if (digit && index === 5 && full.length === 6) {
                queueMicrotask(() => void completePurchasedActivation(full));
            }
            return next;
        });
    };
    const handleCodeKeyDown = (index, e) => {
        if (isRetryLocked)
            return;
        if (e.key === "Backspace" && !codeDigits[index] && index > 0) {
            codeInputRefs.current[index - 1]?.focus();
        }
    };
    const handleCodePaste = (e) => {
        if (isRetryLocked)
            return;
        e.preventDefault();
        const pasted = e.clipboardData
            .getData("text")
            .replace(/\D/g, "")
            .slice(0, 6);
        if (!pasted)
            return;
        setError(null);
        setResendMessage(null);
        const padded = Array.from({ length: 6 }, (_, i) => pasted.charAt(i) || "");
        setCodeDigits(padded);
        const focusIdx = Math.min(pasted.length, 5);
        queueMicrotask(() => codeInputRefs.current[focusIdx]?.focus());
        if (pasted.length === 6) {
            void completePurchasedActivation(pasted);
        }
    };
    return (_jsx(SetupStepLayout, { icon: KeyRound, title: isTrialFlow ? "Start Trial License" : "Enter Activation Code", description: isTrialFlow
            ? "Complete your trial registration. We will store the signed license in Sitecore Settings."
            : "Enter the one-time code sent to your email. We will verify and store your purchased license.", descriptionClassName: "max-w-md leading-relaxed", bodyClassName: "flex flex-col items-center text-center", footer: _jsxs(SetupStepFooter, { children: [_jsx(SetupStepBackButton, { onClick: onBack, disabled: loading }), _jsx("div", { className: "flex-1" }), !isTrialFlow && (_jsx(Button, { type: "button", variant: "ghost", size: "lg", onClick: handleSkip, disabled: loading || resending, children: skipLabel })), _jsx(Button, { type: "submit", form: "license-activation-form", size: "lg", disabled: loading ||
                        isRetryLocked ||
                        (isTrialFlow && !trialFormComplete) ||
                        (!isTrialFlow && !codeComplete), className: "min-w-[220px]", children: loading ? (_jsxs(_Fragment, { children: [_jsx(RefreshCw, { strokeWidth: 1, className: "mr-2 h-4 w-4 animate-spin" }), "Activating..."] })) : (_jsxs(_Fragment, { children: ["Activate License", _jsx(ArrowRight, { className: "ml-2 h-4 w-4", strokeWidth: 1 })] })) })] }), children: _jsxs("form", { id: "license-activation-form", className: "w-full max-w-md", onSubmit: (e) => {
                e.preventDefault();
                if (loading)
                    return;
                if (isTrialFlow && !trialFormComplete)
                    return;
                if (!isTrialFlow && !codeComplete)
                    return;
                void handleActivate();
            }, children: [_jsx("div", { className: "mb-6 space-y-4", children: isTrialFlow ? (_jsxs(_Fragment, { children: [_jsx(Input, { id: "name", value: name, onChange: (e) => setName(e.target.value), placeholder: "Your name", className: "border-border-default focus:ring-feedback-blue h-11 rounded-xl bg-white" }), _jsx(Input, { id: "company", value: companyName, onChange: (e) => setCompanyName(e.target.value), placeholder: "Company name", className: "border-border-default focus:ring-feedback-blue h-11 rounded-xl bg-white" })] })) : (_jsxs(_Fragment, { children: [_jsx("div", { className: "flex justify-center gap-2", "data-testid": "license-code-inputs", children: codeDigits.map((digit, index) => (_jsx("input", { ref: (el) => {
                                        codeInputRefs.current[index] = el;
                                    }, type: "text", inputMode: "numeric", maxLength: 1, "aria-label": `Activation code digit ${index + 1}`, "data-testid": index === 0 ? "license-code-input-0" : undefined, value: digit, onChange: (e) => handleCodeDigitChange(index, e.target.value), onKeyDown: (e) => handleCodeKeyDown(index, e), onPaste: handleCodePaste, disabled: loading || isRetryLocked, className: "border-border-default text-neutral-grey-100 focus:border-highlight-100 focus:ring-highlight-100/20 h-14 w-12 rounded-xl border bg-white text-center text-2xl font-medium focus:ring-2 focus:outline-none disabled:opacity-50" }, index))) }), _jsx("div", { className: "mt-4 text-center", children: _jsx("button", { type: "button", onClick: () => void handleResendCode(), disabled: loading || resending || isResendRetryLocked, className: "text-highlight-100 hover:text-highlight-100 cursor-pointer text-[12px] font-medium underline-offset-4 hover:underline disabled:cursor-not-allowed disabled:opacity-50", children: resending
                                        ? "Resending..."
                                        : isResendRetryLocked
                                            ? `Resend in ${formatRetryTimeSimple(resendRetryAfterSeconds)}`
                                            : resendMessage || "Resend code" }) })] })) }), error && (_jsx(SetupStepError, { className: "mb-8", helper: isRetryLocked
                        ? `Retry available in ${formatRetryTimeSimple(retryAfterSeconds)}`
                        : isResendRetryLocked
                            ? `Resend available in ${formatRetryTimeSimple(resendRetryAfterSeconds)}`
                            : undefined, children: error }))] }) }));
}
//# sourceMappingURL=LicenseActivationStep.js.map