"use client";
import { jsx as _jsx } from "react/jsx-runtime";
import { createContext, useContext, useState, useEffect, useCallback, useRef, } from "react";
import { getLicenseStatus, requestLicense, verifyActivationCode, storeLicense, clearLicenseCache, hasFeature, formatRetryTimeSimple, } from "./licenseService";
import { setupWizardService } from "../setup/services/setupWizardService";
const LicenseContext = createContext(null);
export function useLicense() {
    const context = useContext(LicenseContext);
    if (!context) {
        throw new Error("useLicense must be used within a LicenseProvider");
    }
    return context;
}
export function useLicenseOptional() {
    return useContext(LicenseContext);
}
export function LicenseProvider({ children, initialLicenseStatus, initialStatusLoaded = false, }) {
    const [licenseStatus, setLicenseStatus] = useState(initialLicenseStatus ?? null);
    const [isLoading, setIsLoading] = useState(!initialStatusLoaded);
    const [activationState, setActivationState] = useState("idle");
    const [error, setError] = useState();
    const [activationEmail, setActivationEmail] = useState();
    const [activationRetryAfterSeconds, setActivationRetryAfterSeconds] = useState();
    const activationStateRef = useRef(activationState);
    activationStateRef.current = activationState;
    const applyLicenseStatus = useCallback((status) => {
        setLicenseStatus(status);
        // When licensing is disabled, treat as licensed; no overlay, no license server calls
        if (status.licensingDisabled) {
            setActivationState("idle");
            setError(undefined);
            setActivationRetryAfterSeconds(undefined);
            return;
        }
        // If no valid license is present, start activation in a neutral state.
        // Do not pre-populate error UI before the user attempts an action.
        if (!status.isValid) {
            setError(undefined);
            setActivationRetryAfterSeconds(undefined);
            if (status.status === "no_license") {
                console.log("No license found, showing email entry");
                setActivationState("email_entry");
            }
            else if (status.status === "expired") {
                console.log("License expired, showing email entry");
                setActivationState("email_entry");
            }
            else if (status.status === "build_too_new") {
                console.log("Build too new for license, showing email entry");
                setActivationState("email_entry");
            }
            else if (status.status === "invalid") {
                // License exists but is invalid - show overlay so user can fix it
                console.log("License invalid, showing email entry");
                setActivationState("email_entry");
            }
            return;
        }
        setActivationState("idle");
        setError(undefined);
        setActivationRetryAfterSeconds(undefined);
    }, []);
    // Fetch license status on mount
    const refreshLicenseStatus = useCallback(async () => {
        try {
            setIsLoading(true);
            const status = await getLicenseStatus();
            applyLicenseStatus(status);
        }
        catch (err) {
            console.error("Failed to get license status:", err);
            // Keep initial email entry neutral; show errors only after user-triggered actions.
            setError(undefined);
            setActivationState("email_entry");
        }
        finally {
            setIsLoading(false);
        }
    }, [applyLicenseStatus]);
    useEffect(() => {
        if (initialStatusLoaded) {
            if (initialLicenseStatus) {
                applyLicenseStatus(initialLicenseStatus);
            }
            else {
                setIsLoading(false);
            }
            return;
        }
        refreshLicenseStatus();
    }, [
        applyLicenseStatus,
        initialLicenseStatus,
        initialStatusLoaded,
        refreshLicenseStatus,
    ]);
    // Listen for license validation failures from API calls (e.g. 403 on an action)
    useEffect(() => {
        const handleLicenseValidationFailed = () => {
            setActivationState("email_entry");
            // Only show the error when the user was actually using the app (idle = had valid license).
            // If we're already in email_entry (e.g. no license on load), don't show the error so the
            // overlay stays neutral until the user does something that requires a license.
            if (activationStateRef.current === "idle") {
                setError("License validation failed. Please reactivate your license.");
            }
            setActivationRetryAfterSeconds(undefined);
        };
        window.addEventListener("license:validation-failed", handleLicenseValidationFailed);
        return () => {
            window.removeEventListener("license:validation-failed", handleLicenseValidationFailed);
        };
    }, []);
    const startActivation = useCallback(() => {
        setActivationState("email_entry");
        setError(undefined);
        setActivationEmail(undefined);
        setActivationRetryAfterSeconds(undefined);
    }, []);
    const closeActivation = useCallback(() => {
        if (licenseStatus?.isValid) {
            setActivationState("idle");
        }
    }, [licenseStatus?.isValid]);
    const checkEmail = useCallback(async (email) => {
        setActivationState("loading");
        setError(undefined);
        setActivationEmail(email);
        try {
            // Submit email with placeholder name/company to check license availability
            const response = await requestLicense({
                email,
                name: "Temporary", // Placeholder - will be replaced when trial form is submitted
                companyName: "Temporary", // Placeholder - will be replaced when trial form is submitted
                parheliaBuildDate: licenseStatus?.buildDate || "",
            });
            switch (response.status) {
                case "trial": {
                    const complete = response.license && response.requiresProfileCompletion === false;
                    if (complete) {
                        try {
                            const settingsExist = await setupWizardService.getSettingsExists();
                            if (!settingsExist) {
                                await setupWizardService.createSettingsItem();
                            }
                            const storeResult = await storeLicense(response.license, response.signature);
                            if (storeResult.success) {
                                try {
                                    await clearLicenseCache();
                                }
                                catch (err) {
                                    console.warn("Failed to clear license cache:", err);
                                }
                                await new Promise((resolve) => setTimeout(resolve, 100));
                                await refreshLicenseStatus();
                                setActivationRetryAfterSeconds(undefined);
                                setActivationState("welcome_back");
                                setTimeout(() => {
                                    setActivationState("idle");
                                }, 2000);
                            }
                            else {
                                setError(storeResult.message || "Failed to store license");
                                setActivationState("error");
                            }
                        }
                        catch (persistErr) {
                            console.error("Welcome-back license store failed:", persistErr);
                            setError("Failed to store license");
                            setActivationState("error");
                        }
                    }
                    else {
                        setActivationState("trial_form");
                    }
                    break;
                }
                case "code_sent":
                    // One-time code sent, show code entry form
                    setActivationRetryAfterSeconds(undefined);
                    setActivationState("code_entry");
                    break;
                case "trial_expired":
                    setActivationState("trial_expired");
                    break;
                case "rate_limited":
                    setActivationRetryAfterSeconds(response.retryAfterSeconds || 60);
                    setError(`Too many requests for sending a new code. If you already have a code, enter it now. Otherwise try again in ${formatRetryTimeSimple(response.retryAfterSeconds || 60)}.`);
                    setActivationState("code_entry");
                    break;
                case "error":
                    setActivationRetryAfterSeconds(undefined);
                    setError(response.message || "An error occurred");
                    setActivationState("error");
                    break;
            }
        }
        catch (err) {
            console.error("Email check failed:", err);
            setActivationRetryAfterSeconds(undefined);
            setError("Failed to contact license server");
            setActivationState("error");
        }
    }, [licenseStatus, refreshLicenseStatus]);
    const submitLicenseRequest = useCallback(async (email, name, companyName) => {
        setActivationState("loading");
        setError(undefined);
        setActivationEmail(email);
        setActivationRetryAfterSeconds(undefined);
        try {
            const response = await requestLicense({
                email,
                name,
                companyName,
                parheliaBuildDate: licenseStatus?.buildDate || "",
            });
            switch (response.status) {
                case "trial":
                    // Got a trial license, store it
                    if (response.license) {
                        const settingsExist = await setupWizardService.getSettingsExists();
                        if (!settingsExist) {
                            await setupWizardService.createSettingsItem();
                        }
                        const storeResult = await storeLicense(response.license, response.signature);
                        if (storeResult.success) {
                            // Clear the backend cache and refresh status
                            try {
                                await clearLicenseCache();
                            }
                            catch (err) {
                                console.warn("Failed to clear license cache:", err);
                            }
                            // Wait a bit for the backend to process
                            await new Promise((resolve) => setTimeout(resolve, 100));
                            await refreshLicenseStatus();
                            setActivationRetryAfterSeconds(undefined);
                            setActivationState("success");
                            // Auto-close after success
                            setTimeout(() => {
                                setActivationState("idle");
                            }, 2000);
                        }
                        else {
                            setError(storeResult.message || "Failed to store license");
                            setActivationState("error");
                        }
                    }
                    break;
                case "code_sent":
                    // One-time code sent, show code entry form
                    setActivationRetryAfterSeconds(undefined);
                    setActivationState("code_entry");
                    break;
                case "trial_expired":
                    setActivationState("trial_expired");
                    break;
                case "rate_limited":
                    setActivationRetryAfterSeconds(response.retryAfterSeconds || 60);
                    setError(`Too many requests. Please try again in ${formatRetryTimeSimple(response.retryAfterSeconds || 60)}.`);
                    setActivationState("error");
                    break;
                case "error":
                    setActivationRetryAfterSeconds(undefined);
                    setError(response.message || "An error occurred");
                    setActivationState("error");
                    break;
            }
        }
        catch (err) {
            console.error("License request failed:", err);
            setActivationRetryAfterSeconds(undefined);
            setError("Failed to contact license server");
            setActivationState("error");
        }
    }, [licenseStatus, refreshLicenseStatus]);
    const submitActivationCode = useCallback(async (code) => {
        if (!activationEmail) {
            setError("Email is required");
            return;
        }
        setActivationState("loading");
        setError(undefined);
        setActivationRetryAfterSeconds(undefined);
        try {
            const response = await verifyActivationCode({
                email: activationEmail,
                code,
            });
            switch (response.status) {
                case "purchased":
                    // Got the purchased license, store it
                    if (response.license) {
                        const settingsExist = await setupWizardService.getSettingsExists();
                        if (!settingsExist) {
                            await setupWizardService.createSettingsItem();
                        }
                        const storeResult = await storeLicense(response.license, response.signature);
                        if (storeResult.success) {
                            // Clear the backend cache and refresh status
                            try {
                                await clearLicenseCache();
                            }
                            catch (err) {
                                console.warn("Failed to clear license cache:", err);
                            }
                            // Wait a bit for the backend to process
                            await new Promise((resolve) => setTimeout(resolve, 100));
                            await refreshLicenseStatus();
                            setActivationRetryAfterSeconds(undefined);
                            setActivationState("success");
                            setTimeout(() => {
                                setActivationState("idle");
                            }, 2000);
                        }
                        else {
                            setError(storeResult.message || "Failed to store license");
                            setActivationState("error");
                        }
                    }
                    break;
                case "invalid_code":
                    setActivationRetryAfterSeconds(undefined);
                    setError("Invalid or expired activation code");
                    setActivationState("code_entry");
                    break;
                case "rate_limited":
                    setActivationRetryAfterSeconds(response.retryAfterSeconds || 60);
                    setError(response.message ||
                        `Too many incorrect activation code attempts. Try again in ${formatRetryTimeSimple(response.retryAfterSeconds || 60)}.`);
                    setActivationState("code_entry");
                    break;
                case "error":
                    setActivationRetryAfterSeconds(undefined);
                    setError(response.message || "Verification failed");
                    setActivationState("error");
                    break;
            }
        }
        catch (err) {
            console.error("Code verification failed:", err);
            setActivationRetryAfterSeconds(undefined);
            setError("Failed to verify activation code");
            setActivationState("error");
        }
    }, [licenseStatus, activationEmail, refreshLicenseStatus]);
    const isLicensed = licenseStatus?.isValid ?? false;
    const licenseType = licenseStatus?.licenseType ?? null;
    const features = licenseStatus?.features ?? [];
    const daysRemaining = licenseStatus?.daysRemaining;
    const expiresAt = licenseStatus?.expiresAt
        ? new Date(licenseStatus.expiresAt)
        : undefined;
    const checkFeature = useCallback((feature) => hasFeature(features, feature), [features]);
    const value = {
        licenseStatus,
        isLoading,
        isLicensed,
        licenseType,
        features,
        hasFeature: checkFeature,
        daysRemaining,
        expiresAt,
        activationState,
        error,
        activationRetryAfterSeconds,
        startActivation,
        checkEmail,
        submitLicenseRequest,
        submitActivationCode,
        refreshLicenseStatus,
        closeActivation,
        activationEmail,
    };
    return (_jsx(LicenseContext.Provider, { value: value, children: children }));
}
//# sourceMappingURL=LicenseContext.js.map