import { useCallback } from "react";
import licenseService, { PlanTier } from "@app/services/licenseService";
import { resyncExistingLicense } from "@app/utils/licenseCheckoutUtils";
import {
  CheckoutState,
  PollingStatus,
} from "@app/components/shared/stripeCheckout/types/checkout";

/**
 * Checkout session creation and payment handling hook
 */
export const useCheckoutSession = (
  selectedPlan: PlanTier | null,
  state: CheckoutState,
  setState: React.Dispatch<React.SetStateAction<CheckoutState>>,
  installationId: string | null,
  setInstallationId: React.Dispatch<React.SetStateAction<string | null>>,
  currentLicenseKey: string | null,
  setCurrentLicenseKey: React.Dispatch<React.SetStateAction<string | null>>,
  setPollingStatus: React.Dispatch<React.SetStateAction<PollingStatus>>,
  minimumSeats: number,
  pollForLicenseKey: (installId: string) => Promise<void>,
  onSuccess?: (sessionId: string) => void,
  onError?: (error: string) => void,
  onLicenseActivated?: (licenseInfo: {
    licenseType: string;
    enabled: boolean;
    maxUsers: number;
    hasKey: boolean;
  }) => void,
) => {
  const createCheckoutSession = useCallback(async () => {
    if (!selectedPlan) {
      setState({
        currentStage: "error",
        error: "Selected plan period is not available",
        loading: false,
      });
      return;
    }

    try {
      setState((prev) => ({ ...prev, loading: true }));

      // Fetch installation ID from backend
      let fetchedInstallationId = installationId;
      if (!fetchedInstallationId) {
        fetchedInstallationId = await licenseService.getInstallationId();
        setInstallationId(fetchedInstallationId);
      }

      // Fetch current license key for upgrades
      // Only include if it's a valid PRO/ENTERPRISE license (not NORMAL/free tier)
      let existingLicenseKey: string | undefined;
      try {
        const licenseInfo = await licenseService.getLicenseInfo();
        if (
          licenseInfo?.licenseType &&
          licenseInfo.licenseType !== "NORMAL" &&
          licenseInfo.licenseKey
        ) {
          existingLicenseKey = licenseInfo.licenseKey;
          setCurrentLicenseKey(existingLicenseKey);
          console.log("Found existing valid license for upgrade");
        }
      } catch (error) {
        console.warn(
          "Could not fetch license info, proceeding as new license:",
          error,
        );
      }

      const response = await licenseService.createCheckoutSession({
        lookup_key: selectedPlan.lookupKey,
        installation_id: fetchedInstallationId,
        current_license_key: existingLicenseKey,
        requires_seats: selectedPlan.requiresSeats,
        seat_count: Math.max(1, Math.min(minimumSeats || 1, 10000)),
        email: state.email, // Pass collected email from Stage 1
      });

      // Check if we got a redirect URL (hosted checkout for HTTP)
      if (response.url) {
        console.log("Redirecting to Stripe hosted checkout:", response.url);
        // Redirect to Stripe's hosted checkout page
        window.location.href = response.url;
        return;
      }

      // Otherwise, use embedded checkout (HTTPS)
      setState((prev) => ({
        ...prev,
        clientSecret: response.clientSecret,
        sessionId: response.sessionId,
        loading: false,
      }));
    } catch (err) {
      const errorMessage =
        err instanceof Error
          ? err.message
          : "Failed to create checkout session";
      setState({
        currentStage: "error",
        error: errorMessage,
        loading: false,
      });
      onError?.(errorMessage);
    }
  }, [
    selectedPlan,
    state.email,
    installationId,
    minimumSeats,
    setState,
    setInstallationId,
    setCurrentLicenseKey,
    onError,
  ]);

  const handlePaymentComplete = useCallback(async () => {
    // Preserve state when changing stage
    setState((prev) => ({ ...prev, currentStage: "success" }));

    // Check if this is an upgrade (existing license key) or new plan
    if (currentLicenseKey) {
      // UPGRADE FLOW: Resync existing license with Keygen
      console.log("Upgrade detected - resyncing existing license with Keygen");
      setPollingStatus("polling");

      const activation = await resyncExistingLicense({
        isMounted: () => true, // Modal is open, no need to check
        onActivated: onLicenseActivated,
      });

      if (activation.success) {
        console.log(`License upgraded successfully: ${activation.licenseType}`);
        setPollingStatus("ready");
      } else {
        console.error("Failed to sync upgraded license:", activation.error);
        setPollingStatus("timeout");
      }

      // Notify parent (don't wait - upgrade is complete)
      onSuccess?.(state.sessionId || "");
    } else {
      // NEW PLAN FLOW: Poll for new license key
      console.log("New subscription - polling for license key");

      if (installationId) {
        pollForLicenseKey(installationId).finally(() => {
          // Only notify parent after polling completes or times out
          onSuccess?.(state.sessionId || "");
        });
      } else {
        // No installation ID, notify immediately
        onSuccess?.(state.sessionId || "");
      }
    }
  }, [
    currentLicenseKey,
    installationId,
    state.sessionId,
    setState,
    setPollingStatus,
    pollForLicenseKey,
    onSuccess,
    onLicenseActivated,
  ]);

  return {
    createCheckoutSession,
    handlePaymentComplete,
  };
};
