import Modal, { ModalWidth } from "../Modal/Modal";
import Icon, { IconType, SizeProp } from "../Icon/Icon";
import IconProp from "../../../Types/Icon/IconProp";
import Input from "../Input/Input";
import Button, { ButtonStyleType } from "../Button/Button";
import React, { useCallback, useEffect, useMemo, useRef, useState, } from "react";
import GlobalConfig from "../../../Models/DatabaseModels/GlobalConfig";
import API from "../../Utils/API/API";
import OneUptimeDate from "../../../Types/Date";
import HTTPMethod from "../../../Types/API/HTTPMethod";
import Route from "../../../Types/API/Route";
import URL from "../../../Types/API/URL";
import { APP_API_URL, BILLING_ENABLED, IS_ENTERPRISE_EDITION, } from "../../Config";
import Alert, { AlertType } from "../Alerts/Alert";
const ENTERPRISE_URL = "https://oneuptime.com/enterprise/demo";
const EditionLabel = (props) => {
    const [isDialogOpen, setIsDialogOpen] = useState(false);
    const [globalConfig, setGlobalConfig] = useState(null);
    const [isConfigLoading, setIsConfigLoading] = useState(false);
    const [configError, setConfigError] = useState("");
    const [licenseKeyInput, setLicenseKeyInput] = useState("");
    const [validationError, setValidationError] = useState("");
    const [successMessage, setSuccessMessage] = useState("");
    const [isValidating, setIsValidating] = useState(false);
    const licenseInputEditedRef = useRef(false);
    if (BILLING_ENABLED) {
        return React.createElement(React.Fragment, null);
    }
    const fetchGlobalConfig = useCallback(async () => {
        if (!IS_ENTERPRISE_EDITION) {
            return;
        }
        setIsConfigLoading(true);
        setConfigError("");
        try {
            const licenseUrl = URL.fromURL(APP_API_URL).addRoute(new Route("/global-config/license"));
            const response = await API.fetch({
                method: HTTPMethod.GET,
                url: licenseUrl,
            });
            if (!response.isSuccess()) {
                throw response;
            }
            const payload = response.data;
            const configModel = new GlobalConfig();
            if (payload["companyName"]) {
                configModel.enterpriseCompanyName = payload["companyName"];
            }
            if (payload["licenseKey"]) {
                configModel.enterpriseLicenseKey = payload["licenseKey"];
            }
            if (payload["token"]) {
                configModel.enterpriseLicenseToken = payload["token"];
            }
            if (payload["expiresAt"]) {
                configModel.enterpriseLicenseExpiresAt = OneUptimeDate.fromString(payload["expiresAt"]);
            }
            if (typeof payload["userLimit"] === "number") {
                configModel.enterpriseLicenseUserLimit = payload["userLimit"];
            }
            if (typeof payload["currentUserCount"] === "number") {
                configModel.enterpriseLicenseCurrentUserCount = payload["currentUserCount"];
            }
            if (payload["userCountUpdatedAt"]) {
                configModel.enterpriseLicenseUserCountUpdatedAt =
                    OneUptimeDate.fromString(payload["userCountUpdatedAt"]);
            }
            setGlobalConfig(configModel);
            if (!licenseInputEditedRef.current) {
                setLicenseKeyInput(configModel.enterpriseLicenseKey || "");
            }
        }
        catch (err) {
            setGlobalConfig(null);
            setConfigError(API.getFriendlyMessage(err));
        }
        finally {
            setIsConfigLoading(false);
        }
    }, []);
    useEffect(() => {
        void fetchGlobalConfig();
    }, [fetchGlobalConfig]);
    const licenseValid = useMemo(() => {
        if (!IS_ENTERPRISE_EDITION) {
            return false;
        }
        if (!(globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.enterpriseLicenseToken) ||
            !globalConfig.enterpriseLicenseExpiresAt) {
            return false;
        }
        const expiresAt = OneUptimeDate.fromString(globalConfig.enterpriseLicenseExpiresAt);
        return expiresAt.getTime() > Date.now();
    }, [
        globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.enterpriseLicenseExpiresAt,
        globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.enterpriseLicenseToken,
    ]);
    const licenseExpiresAtText = useMemo(() => {
        if (!(globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.enterpriseLicenseExpiresAt)) {
            return null;
        }
        const expiresAt = OneUptimeDate.fromString(globalConfig.enterpriseLicenseExpiresAt);
        if (Number.isNaN(expiresAt.getTime())) {
            return null;
        }
        return expiresAt.toLocaleString();
    }, [globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.enterpriseLicenseExpiresAt]);
    const userLimit = useMemo(() => {
        return typeof (globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.enterpriseLicenseUserLimit) === "number"
            ? globalConfig.enterpriseLicenseUserLimit
            : null;
    }, [globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.enterpriseLicenseUserLimit]);
    const currentUserCount = useMemo(() => {
        return typeof (globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.enterpriseLicenseCurrentUserCount) === "number"
            ? globalConfig.enterpriseLicenseCurrentUserCount
            : null;
    }, [globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.enterpriseLicenseCurrentUserCount]);
    const userCountUpdatedAtText = useMemo(() => {
        if (!(globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.enterpriseLicenseUserCountUpdatedAt)) {
            return null;
        }
        const reportedAt = OneUptimeDate.fromString(globalConfig.enterpriseLicenseUserCountUpdatedAt);
        if (Number.isNaN(reportedAt.getTime())) {
            return null;
        }
        return reportedAt.toLocaleString();
    }, [globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.enterpriseLicenseUserCountUpdatedAt]);
    const isUserLimitBreached = useMemo(() => {
        if (!licenseValid) {
            return false;
        }
        if (typeof userLimit !== "number" || userLimit <= 0) {
            return false;
        }
        if (typeof currentUserCount !== "number") {
            return false;
        }
        return currentUserCount > userLimit;
    }, [licenseValid, userLimit, currentUserCount]);
    const userUsagePercent = useMemo(() => {
        if (typeof userLimit !== "number" || userLimit <= 0) {
            return null;
        }
        if (typeof currentUserCount !== "number") {
            return null;
        }
        return Math.min(100, Math.max(0, Math.round((currentUserCount / userLimit) * 100)));
    }, [userLimit, currentUserCount]);
    const editionName = useMemo(() => {
        if (!IS_ENTERPRISE_EDITION) {
            return "Community Edition";
        }
        if (isConfigLoading) {
            return "Enterprise Edition (Checking...)";
        }
        return licenseValid
            ? "Enterprise Edition"
            : "Enterprise Edition (License Required)";
    }, [isConfigLoading, licenseValid]);
    const indicatorColor = useMemo(() => {
        if (!IS_ENTERPRISE_EDITION) {
            return "bg-indigo-400";
        }
        if (isConfigLoading) {
            return "bg-yellow-400";
        }
        if (!licenseValid) {
            return "bg-red-500";
        }
        if (isUserLimitBreached) {
            return "bg-red-500";
        }
        return "bg-emerald-500";
    }, [isConfigLoading, licenseValid, isUserLimitBreached]);
    const ctaLabel = useMemo(() => {
        if (!IS_ENTERPRISE_EDITION) {
            return "Learn more";
        }
        if (isConfigLoading) {
            return "Checking";
        }
        if (!licenseValid) {
            return "Validate license";
        }
        if (isUserLimitBreached) {
            return "User limit exceeded";
        }
        return "View details";
    }, [isConfigLoading, licenseValid, isUserLimitBreached]);
    const communityFeatures = useMemo(() => {
        return [
            "Full OneUptime platform with incident response, status pages, and workflow automation.",
            "Community support, documentation, and tutorials to help teams get started quickly.",
            "Regular updates, bug fixes, and open-source extensibility.",
            "Integrations with popular DevOps tools through community-maintained connectors.",
        ];
    }, []);
    const enterpriseFeatures = useMemo(() => {
        return [
            "Enterprise (hardened and secure) Docker images.",
            "Dedicated enterprise support phone number available 24/7/365.",
            "Priority chat and email support.",
            "Dedicated engineer who can build custom features to integrate OneUptime with your ecosystem.",
            "Compliance reports (ISO, SOC, GDPR, HIPAA).",
            "Legal indemnification.",
            "Audit logs and many more enterprise-focused features.",
        ];
    }, []);
    const openDialog = () => {
        setIsDialogOpen(true);
        setValidationError("");
        setSuccessMessage("");
        if (IS_ENTERPRISE_EDITION) {
            void fetchGlobalConfig();
        }
    };
    const closeDialog = () => {
        setIsDialogOpen(false);
        setValidationError("");
        setSuccessMessage("");
    };
    const handlePrimaryAction = () => {
        if (typeof window !== "undefined") {
            window.open(ENTERPRISE_URL, "_blank", "noopener,noreferrer");
        }
        closeDialog();
    };
    const runLicenseValidation = useCallback(async (key, setLoading) => {
        const trimmedKey = key.trim();
        if (!trimmedKey) {
            setValidationError("Please enter a license key before validating.");
            setSuccessMessage("");
            return;
        }
        setValidationError("");
        setSuccessMessage("");
        setLoading(true);
        try {
            const validationUrl = URL.fromURL(APP_API_URL).addRoute(new Route("/global-config/license"));
            const response = await API.fetch({
                method: HTTPMethod.POST,
                url: validationUrl,
                data: {
                    licenseKey: trimmedKey,
                },
            });
            if (!response.isSuccess()) {
                throw response;
            }
            const payload = response.data;
            licenseInputEditedRef.current = false;
            setLicenseKeyInput(payload["licenseKey"] || trimmedKey);
            setSuccessMessage("License validated successfully.");
            await fetchGlobalConfig();
        }
        catch (err) {
            setValidationError(API.getFriendlyMessage(err));
        }
        finally {
            setLoading(false);
        }
    }, [fetchGlobalConfig]);
    const handleValidateClick = () => {
        if (isValidating) {
            return;
        }
        void runLicenseValidation(licenseKeyInput, setIsValidating);
    };
    const handleRetryFetch = () => {
        if (!isConfigLoading) {
            void fetchGlobalConfig();
        }
    };
    const shouldShowEnterpriseValidationButton = IS_ENTERPRISE_EDITION && !licenseValid;
    const modalSubmitButtonText = IS_ENTERPRISE_EDITION
        ? shouldShowEnterpriseValidationButton
            ? "Validate License"
            : undefined
        : "Talk to Sales";
    const modalOnSubmit = IS_ENTERPRISE_EDITION
        ? shouldShowEnterpriseValidationButton
            ? handleValidateClick
            : undefined
        : handlePrimaryAction;
    const modalIsLoading = IS_ENTERPRISE_EDITION && shouldShowEnterpriseValidationButton
        ? isValidating
        : false;
    const modalDisableSubmitButton = IS_ENTERPRISE_EDITION
        ? shouldShowEnterpriseValidationButton
            ? !licenseKeyInput.trim() || isValidating || isConfigLoading
            : undefined
        : false;
    const showAlertedPill = IS_ENTERPRISE_EDITION &&
        !isConfigLoading &&
        (isUserLimitBreached ||
            (!licenseValid && Boolean(globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.enterpriseLicenseKey)));
    const pillClassName = showAlertedPill
        ? "group inline-flex items-center gap-2 rounded-full border border-red-200 bg-red-50 px-3 py-1 text-xs font-medium text-red-700 shadow-sm transition hover:border-red-300 hover:bg-red-100 focus:outline-none focus-visible:ring-2 focus-visible:ring-red-400"
        : "group inline-flex items-center gap-2 rounded-full border border-indigo-100 bg-white px-3 py-1 text-xs font-medium text-indigo-700 shadow-sm transition hover:border-indigo-300 hover:bg-indigo-50 focus:outline-none focus-visible:ring-2 focus-visible:ring-indigo-400";
    const pillCtaTextClassName = showAlertedPill
        ? "text-[11px] text-red-500 group-hover:text-red-600"
        : "text-[11px] text-indigo-500 group-hover:text-indigo-600";
    return (React.createElement(React.Fragment, null,
        React.createElement("button", { type: "button", onClick: openDialog, className: `${pillClassName} ${props.className ? props.className : ""}`, "aria-label": `${editionName} details` },
            showAlertedPill && (React.createElement(Icon, { icon: IconProp.Alert, size: SizeProp.Small, className: "text-red-600" })),
            React.createElement("span", { className: `h-2 w-2 rounded-full transition group-hover:scale-110 ${indicatorColor}` }),
            React.createElement("span", { className: "tracking-wide" }, editionName),
            React.createElement("span", { className: pillCtaTextClassName }, ctaLabel)),
        isDialogOpen && (React.createElement(Modal, { title: editionName, submitButtonText: modalSubmitButtonText, closeButtonText: "Close", onClose: closeDialog, onSubmit: modalOnSubmit, modalWidth: ModalWidth.Large, isLoading: modalIsLoading, disableSubmitButton: modalDisableSubmitButton, isBodyLoading: IS_ENTERPRISE_EDITION ? isConfigLoading : false },
            React.createElement("div", { className: "space-y-3 text-sm text-gray-600" }, IS_ENTERPRISE_EDITION ? (React.createElement(React.Fragment, null,
                configError && (React.createElement("div", { className: "rounded-md border border-red-200 bg-red-50 p-3 text-sm text-red-700" },
                    React.createElement("p", { className: "font-semibold" }, "Unable to load license details"),
                    React.createElement("p", { className: "mt-1" }, configError),
                    React.createElement("div", { className: "mt-3 -ml-3" },
                        React.createElement(Button, { title: "Retry", buttonStyle: ButtonStyleType.DANGER, onClick: handleRetryFetch, isLoading: isConfigLoading })))),
                !configError && !isConfigLoading && licenseValid && (React.createElement("div", { className: "rounded-md border border-emerald-200 bg-emerald-50 p-3 text-sm text-emerald-700" },
                    React.createElement("p", { className: "font-semibold" }, "License verified"),
                    React.createElement("p", { className: "mt-1" },
                        React.createElement("span", { className: "font-medium" }, "Company:"),
                        " ",
                        (globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.enterpriseCompanyName) || "Not specified"),
                    licenseExpiresAtText && (React.createElement("p", null,
                        React.createElement("span", { className: "font-medium" }, "Expires:"),
                        " ",
                        licenseExpiresAtText)))),
                !configError && !isConfigLoading && licenseValid && (React.createElement("div", { className: `rounded-lg border p-4 shadow-sm ${isUserLimitBreached
                        ? "border-red-200 bg-red-50"
                        : "border-gray-200 bg-white"}` },
                    React.createElement("div", { className: "flex items-start gap-3" },
                        React.createElement("div", { className: `flex h-9 w-9 items-center justify-center rounded-full ${isUserLimitBreached
                                ? "bg-red-100 text-red-600"
                                : "bg-indigo-100 text-indigo-600"}` },
                            React.createElement(Icon, { icon: isUserLimitBreached ? IconProp.Alert : IconProp.User, size: SizeProp.Regular })),
                        React.createElement("div", { className: "flex-1" },
                            React.createElement("div", { className: "flex items-center justify-between" },
                                React.createElement("h3", { className: `text-sm font-semibold ${isUserLimitBreached
                                        ? "text-red-900"
                                        : "text-gray-900"}` }, "User Usage"),
                                isUserLimitBreached && (React.createElement("span", { className: "inline-flex items-center gap-1 rounded-full bg-red-100 px-2 py-0.5 text-xs font-medium text-red-700" }, "Limit exceeded"))),
                            React.createElement("div", { className: "mt-2 flex items-baseline gap-1" },
                                React.createElement("span", { className: `text-2xl font-semibold ${isUserLimitBreached
                                        ? "text-red-700"
                                        : "text-gray-900"}` }, typeof currentUserCount === "number"
                                    ? currentUserCount.toLocaleString()
                                    : "—"),
                                React.createElement("span", { className: "text-sm text-gray-500" },
                                    " / ",
                                    typeof userLimit === "number" && userLimit > 0
                                        ? `${userLimit.toLocaleString()} users`
                                        : "unlimited")),
                            typeof userUsagePercent === "number" && (React.createElement("div", { className: "mt-3" },
                                React.createElement("div", { className: "h-2 w-full overflow-hidden rounded-full bg-gray-200" },
                                    React.createElement("div", { className: `h-full rounded-full transition-all ${isUserLimitBreached
                                            ? "bg-red-500"
                                            : userUsagePercent >= 80
                                                ? "bg-amber-500"
                                                : "bg-emerald-500"}`, style: { width: `${userUsagePercent}%` } })),
                                React.createElement("p", { className: "mt-1 text-xs text-gray-500" },
                                    userUsagePercent,
                                    "% of licensed seats in use"))),
                            isUserLimitBreached && (React.createElement("p", { className: "mt-3 text-xs text-red-700" },
                                "Your installation has more users than your license permits. Please contact",
                                " ",
                                React.createElement("a", { href: "mailto:sales@oneuptime.com", className: "font-medium text-red-800 underline hover:text-red-900" }, "sales@oneuptime.com"),
                                " ",
                                "to expand your license.")),
                            React.createElement("p", { className: "mt-3 text-xs text-gray-500" }, userCountUpdatedAtText
                                ? `Last reported to OneUptime on ${userCountUpdatedAtText}.`
                                : "User count has not been reported to OneUptime yet. The first report will be sent within 24 hours."))))),
                !configError &&
                    !isConfigLoading &&
                    !licenseValid &&
                    (globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.enterpriseLicenseKey) && (React.createElement("div", { className: "rounded-md border border-red-200 bg-red-50 p-3 text-sm text-red-700" },
                    React.createElement("p", { className: "font-semibold" }, "License validation required"),
                    React.createElement("p", { className: "mt-1" }, "The stored license information could not be verified. Please validate the license key again."))),
                !configError && (React.createElement(React.Fragment, null,
                    successMessage && (React.createElement(Alert, { type: AlertType.SUCCESS, title: successMessage })),
                    !licenseValid && (React.createElement(React.Fragment, null,
                        React.createElement("div", null,
                            React.createElement("label", { className: "text-sm font-medium text-gray-700" }, "License Key"),
                            React.createElement(Input, { value: licenseKeyInput, onChange: (value) => {
                                    setLicenseKeyInput(value);
                                    licenseInputEditedRef.current = true;
                                }, placeholder: "Enter your enterprise license key", disableSpellCheck: true })),
                        validationError && (React.createElement(Alert, { type: AlertType.DANGER, title: validationError })),
                        React.createElement("p", { className: "text-xs text-gray-500" },
                            "You have installed Enterprise Edition of OneUptime. You need to validate your license key. Need a license key? Contact our sales team at",
                            " ",
                            React.createElement("a", { href: "mailto:sales@oneuptime.com", className: "font-medium text-indigo-600 hover:text-indigo-700" }, "sales@oneuptime.com"),
                            "."))))),
                React.createElement("div", { className: "rounded-lg border border-indigo-200 bg-indigo-50 p-4 shadow-sm" },
                    React.createElement("h3", { className: "text-sm font-semibold text-indigo-900" }, "Enterprise Edition Features"),
                    React.createElement("ul", { className: "mt-3 space-y-2 text-sm text-indigo-900" }, enterpriseFeatures.map((feature, index) => {
                        return (React.createElement("li", { key: index, className: "flex items-start gap-2" },
                            React.createElement(Icon, { icon: IconProp.Check, type: IconType.Success, size: SizeProp.Small, className: "mt-0.5" }),
                            React.createElement("span", { className: "leading-snug" }, feature)));
                    })),
                    React.createElement("p", { className: "mt-3 text-xs text-indigo-700" }, "Already have a license? Validate it above to unlock these premium capabilities immediately.")))) : (React.createElement(React.Fragment, null,
                React.createElement("p", null, "You are running the Community Edition of OneUptime. Here is a quick comparison to help you decide if Enterprise is the right fit for your team."),
                React.createElement("div", { className: "grid gap-4 md:grid-cols-2" },
                    React.createElement("div", { className: "rounded-lg border border-gray-200 bg-white p-4 shadow-sm" },
                        React.createElement("h3", { className: "text-sm font-semibold text-gray-900" }, "Community Edition"),
                        React.createElement("ul", { className: "mt-3 space-y-2 text-sm text-gray-600" }, communityFeatures.map((feature, index) => {
                            return (React.createElement("li", { key: index, className: "flex items-start gap-2" },
                                React.createElement(Icon, { icon: IconProp.Check, size: SizeProp.Small, className: "mt-0.5 text-gray-400" }),
                                React.createElement("span", { className: "leading-snug" }, feature)));
                        })),
                        React.createElement("p", { className: "mt-3 text-xs text-gray-500" }, "Best for small teams experimenting with reliability workflows.")),
                    React.createElement("div", { className: "rounded-lg border border-indigo-200 bg-indigo-50 p-4 shadow-sm" },
                        React.createElement("h3", { className: "text-sm font-semibold text-indigo-900" }, "Enterprise Edition"),
                        React.createElement("ul", { className: "mt-3 space-y-2 text-sm text-indigo-900" }, enterpriseFeatures.map((feature, index) => {
                            return (React.createElement("li", { key: index, className: "flex items-start gap-2" },
                                React.createElement(Icon, { icon: IconProp.Check, type: IconType.Success, size: SizeProp.Small, className: "mt-0.5" }),
                                React.createElement("span", { className: "leading-snug" }, feature)));
                        })),
                        React.createElement("p", { className: "mt-3 text-xs text-indigo-700" }, "Everything in Community plus white-glove onboarding, enterprise SLAs, and a partner dedicated to your reliability goals."))),
                React.createElement("p", { className: "text-xs text-gray-500" }, "Ready to unlock enterprise capabilities? Click \"Talk to Sales\" to start the conversation."))))))));
};
export default EditionLabel;
//# sourceMappingURL=EditionLabel.js.map