import React, { useState, useEffect, useCallback } from "react";
import { useTranslation } from "react-i18next";
import { useNavigate, useLocation } from "react-router-dom";
import { isAuthRoute } from "@core/constants/routes";
import { useCheckout } from "@app/contexts/CheckoutContext";
import { InfoBanner } from "@app/components/shared/InfoBanner";
import {
  SERVER_LICENSE_REQUEST_EVENT,
  type ServerLicenseRequestPayload,
  UPGRADE_BANNER_TEST_EVENT,
  type UpgradeBannerTestPayload,
  type UpgradeBannerTestScenario,
  UPGRADE_BANNER_ALERT_EVENT,
} from "@core/constants/events";
import { useServerExperience } from "@app/hooks/useServerExperience";
import { isOnboardingCompleted } from "@core/components/onboarding/orchestrator/onboardingStorage";

const FRIENDLY_LAST_SEEN_KEY = "upgradeBannerFriendlyLastShownAt";
const WEEK_IN_MS = 7 * 24 * 60 * 60 * 1000;
const UpgradeBanner: React.FC = () => {
  const { t } = useTranslation();
  const navigate = useNavigate();
  const location = useLocation();

  // Check if we're on an auth route (evaluated after hooks, used in render)
  const onAuthRoute = isAuthRoute(location.pathname);
  const { openCheckout } = useCheckout();
  const {
    loginEnabled,
    totalUsers,
    userCountResolved,
    userCountLoading,
    effectiveIsAdmin: configIsAdmin,
    hasPaidLicense,
    licenseLoading,
    freeTierLimit,
    overFreeTierLimit,
    weeklyActiveUsers,
    scenarioKey,
  } = useServerExperience();
  const onboardingComplete = isOnboardingCompleted();
  const [friendlyVisible, setFriendlyVisible] = useState(() => {
    if (typeof window === "undefined") return false;
    const lastShownRaw = window.localStorage.getItem(FRIENDLY_LAST_SEEN_KEY);
    if (!lastShownRaw) return false;
    const lastShown = parseInt(lastShownRaw, 10);
    if (!Number.isFinite(lastShown)) return false;
    return Date.now() - lastShown >= WEEK_IN_MS;
  });
  const isDev = import.meta.env.DEV;
  const [testScenario, setTestScenario] = useState<UpgradeBannerTestScenario>(null);

  useEffect(() => {
    if (!isDev || typeof window === "undefined") {
      return;
    }

    const handleTestEvent = (event: Event) => {
      const { detail } = event as CustomEvent<UpgradeBannerTestPayload>;
      setTestScenario(detail?.scenario ?? null);

      if (detail?.scenario === "friendly") {
        setFriendlyVisible(true);
      } else if (!detail?.scenario) {
        setFriendlyVisible(false);
      }
    };

    window.addEventListener(UPGRADE_BANNER_TEST_EVENT, handleTestEvent as EventListener);
    return () => {
      window.removeEventListener(UPGRADE_BANNER_TEST_EVENT, handleTestEvent as EventListener);
    };
  }, [isDev]);

  const isAdmin = configIsAdmin;

  const scenario = isDev ? testScenario : null;
  const scenarioIsFriendly = scenario === "friendly";
  const scenarioIsUrgentUser = scenario === "urgent-user";

  const userCountKnown = typeof totalUsers === "number";
  const isUnderLimit = userCountKnown ? totalUsers < freeTierLimit : null;
  const isOverLimit = userCountKnown ? totalUsers > freeTierLimit : overFreeTierLimit;
  const baseTotalUsersLoaded = userCountResolved && !userCountLoading;

  const scenarioProvidesInfo = scenarioKey && scenarioKey !== "unknown" && scenarioKey !== "licensed";
  const derivedIsAdmin = scenarioProvidesInfo ? scenarioKey.includes("admin") : isAdmin;
  const derivedHasPaidLicense = scenarioKey === "licensed" ? true : scenarioKey === "unknown" ? hasPaidLicense : false;
  const derivedIsUnderLimit = scenarioProvidesInfo ? scenarioKey.includes("under-limit") : isUnderLimit === true;
  const derivedIsOverLimit = scenarioProvidesInfo ? scenarioKey.includes("over-limit") : isOverLimit === true;

  const effectiveIsAdmin = scenario ? (scenarioIsUrgentUser ? false : true) : derivedIsAdmin;
  const effectiveTotalUsers = scenario != null ? (scenarioIsFriendly ? 3 : 8) : totalUsers;
  const effectiveTotalUsersLoaded = scenario != null ? true : baseTotalUsersLoaded;
  const effectiveHasPaidLicense = scenario != null ? false : derivedHasPaidLicense;
  const effectiveIsUnderLimit = scenario != null ? scenarioIsFriendly : derivedIsUnderLimit;
  const effectiveIsOverLimit = scenario != null ? !scenarioIsFriendly : derivedIsOverLimit;

  const isDerivedAdmin = scenario
    ? !scenarioIsUrgentUser
    : scenarioKey === "login-user-over-limit-no-license"
      ? false
      : effectiveIsAdmin;

  const shouldShowFriendlyBase = Boolean(
    isDerivedAdmin && !effectiveHasPaidLicense && effectiveIsUnderLimit && effectiveTotalUsersLoaded,
  );
  const shouldShowUrgentBase = Boolean(
    !effectiveHasPaidLicense &&
    effectiveTotalUsersLoaded &&
    (effectiveIsOverLimit || scenarioKey === "login-user-over-limit-no-license"),
  );

  const shouldEvaluateFriendly = scenario
    ? scenarioIsFriendly
    : Boolean(shouldShowFriendlyBase && !licenseLoading && effectiveTotalUsersLoaded && onboardingComplete);
  // Urgent banner should always show when over-limit
  const shouldEvaluateUrgent = scenario
    ? Boolean(scenario && !scenarioIsFriendly)
    : Boolean(shouldShowUrgentBase && !licenseLoading);

  useEffect(() => {
    if (scenario === "friendly") {
      return;
    }

    if (!shouldEvaluateFriendly) {
      setFriendlyVisible(false);
      return;
    }

    if (friendlyVisible || typeof window === "undefined" || userCountLoading) {
      return;
    }

    const lastShownRaw = window.localStorage.getItem(FRIENDLY_LAST_SEEN_KEY);
    const lastShown = lastShownRaw ? parseInt(lastShownRaw, 10) : 0;
    const now = Date.now();
    const due = !Number.isFinite(lastShown) || now - lastShown >= WEEK_IN_MS;
    setFriendlyVisible(due);
  }, [scenario, shouldEvaluateFriendly, friendlyVisible, userCountLoading]);

  useEffect(() => {
    if (typeof window === "undefined") {
      return;
    }

    const detail = shouldEvaluateUrgent
      ? {
          active: true,
          audience: effectiveIsAdmin ? "admin" : "user",
          totalUsers: effectiveTotalUsers ?? null,
          freeTierLimit,
        }
      : { active: false };

    window.dispatchEvent(new CustomEvent(UPGRADE_BANNER_ALERT_EVENT, { detail }));
  }, [shouldEvaluateUrgent, effectiveIsAdmin, effectiveTotalUsers, scenario, freeTierLimit]);

  useEffect(() => {
    return () => {
      if (typeof window !== "undefined") {
        window.dispatchEvent(new CustomEvent(UPGRADE_BANNER_ALERT_EVENT, { detail: { active: false } }));
      }
    };
  }, []);

  const recordFriendlyLastShown = useCallback(() => {
    if (typeof window === "undefined") {
      return;
    }
    window.localStorage.setItem(FRIENDLY_LAST_SEEN_KEY, Date.now().toString());
  }, []);

  const handleUpgrade = () => {
    recordFriendlyLastShown();

    const hideBanner = () => setFriendlyVisible(false);
    const navigateFallback = () => {
      navigate("/settings/adminPlan");
      hideBanner();
    };

    try {
      openCheckout("server", {
        minimumSeats: 1,
        onSuccess: () => {
          hideBanner();
        },
        onError: () => {
          navigateFallback();
        },
      });
    } catch (error) {
      console.error("[UpgradeBanner] Failed to open checkout, redirecting instead", error);
      navigateFallback();
      return;
    }

    // Keep legacy behavior so banner disappears once the user initiates checkout
    hideBanner();
  };

  const handleFriendlyDismiss = () => {
    recordFriendlyLastShown();
    setFriendlyVisible(false);
  };

  const handleSeeInfo = () => {
    if (typeof window === "undefined" || !effectiveIsAdmin) {
      return;
    }

    const detail: ServerLicenseRequestPayload = {
      licenseNotice: {
        totalUsers: effectiveTotalUsers ?? null,
        freeTierLimit,
        isOverLimit: effectiveIsOverLimit ?? false,
      },
      selfReportedAdmin: true,
      deferUntilTourComplete: false,
    };

    window.dispatchEvent(new CustomEvent(SERVER_LICENSE_REQUEST_EVENT, { detail }));
  };

  const renderUrgentBanner = () => {
    if (!shouldEvaluateUrgent) {
      return null;
    }

    const buttonText = effectiveIsAdmin ? t("upgradeBanner.seeInfo", "See info") : undefined;

    const attentionMessage = effectiveIsAdmin
      ? t("upgradeBanner.attentionBodyAdmin", "Review the license requirements to keep this server compliant.")
      : t("upgradeBanner.attentionBody", "Your admin needs to sign in to see more info. Please contact them immediately.");

    return (
      <InfoBanner
        icon="warning-rounded"
        tone="warning"
        title={t("upgradeBanner.attentionTitle", "This server needs admin attention")}
        message={attentionMessage}
        buttonText={buttonText}
        buttonIcon="info-rounded"
        onButtonClick={buttonText ? handleSeeInfo : undefined}
        dismissible={false}
        minHeight={60}
        background="#FFF4E6"
        borderColor="var(--mantine-color-orange-7)"
        textColor="#9A3412"
        iconColor="#EA580C"
        buttonVariant="filled"
        buttonColor="orange.7"
      />
    );
  };

  const suppressForNoLogin = !loginEnabled || (!loginEnabled && (weeklyActiveUsers ?? Number.POSITIVE_INFINITY) > 5);

  // Don't show on auth routes or if neither banner type should show
  // Also suppress entirely for no-login servers (treat them as regular users only)
  // and, per request, never surface upgrade messaging there when WAU > 5.
  if (onAuthRoute || suppressForNoLogin || (!friendlyVisible && !shouldEvaluateUrgent)) {
    return null;
  }

  return (
    <>
      {friendlyVisible && (
        <InfoBanner
          icon="stars-rounded"
          title={t("upgradeBanner.title", "Upgrade to Server Plan")}
          message={t("upgradeBanner.message", "Get the most out of Stirling PDF with unlimited users and advanced features.")}
          buttonText={t("upgradeBanner.upgradeButton", "Upgrade Now")}
          buttonIcon="upgrade-rounded"
          onButtonClick={handleUpgrade}
          onDismiss={handleFriendlyDismiss}
          show={friendlyVisible}
          background="linear-gradient(135deg, #667eea 0%, #764ba2 100%)"
          borderColor="transparent"
          textColor="#fff"
          iconColor="#fff"
          closeIconColor="#fff"
          buttonVariant="white"
          buttonColor="blue"
          minHeight={64}
        />
      )}
      {renderUrgentBanner()}
    </>
  );
};

export default UpgradeBanner;
