'use client';

import { useAuth, useUser } from '@clerk/nextjs';
import { observer } from 'mobx-react-lite';
import { useRouter, useSearchParams } from 'next/navigation';
import { useEffect, useRef, useState } from 'react';

import { useStores } from '@/app/(root)/AppProviders';
import { Currency } from '@/app/(root)/account/constants';
import { AXON_ITEM_CATEGORY_ID } from '@/components/ga4/constants';
import {
  createAxonItemVariantIdForSubscription,
  useAxon,
} from '@/components/ga4/useAxon';
import SpinnerSVG from '@/components/svg/SpinnerSVG';
import { useSproutTracking } from '@/hooks/useSproutTracking';
import { useApiClient } from '@/lib/apiClient';
import { type CheckoutSource } from '@/lib/checkoutSource';
import {
  CheckoutSession,
  PlanKey,
  UsagePlanSchema,
} from '@/state/sessionStore';
import { SubscriptionPeriod } from '@/utils/session';

const RedirectPageClient = observer(() => {
  const router = useRouter();
  const searchParams = useSearchParams();
  const { isLoaded, isSignedIn } = useAuth();
  const { user: clerkUser } = useUser();
  const apiClient = useApiClient();
  const { session } = useStores();
  const {
    publishBeginCheckoutEvent: publishAxonBeginCheckoutEvent,
    publishAddToCartEvent: publishAxonAddToCartEvent,
  } = useAxon();
  const { getSproutAffiliateIdForApi } = useSproutTracking();
  const [isProcessing, setIsProcessing] = useState(false);
  const hasProcessedRef = useRef(false);

  // Validate URL parameters and extract checkout details
  const validateAndExtractParams = () => {
    const planKey = searchParams.get('plan_key') as PlanKey;
    const period = searchParams.get('period') as SubscriptionPeriod;
    const checkoutSourceParam = searchParams.get('checkout_source');
    const currency = (searchParams.get('currency') || Currency.USD) as Currency;
    const checkoutSource = checkoutSourceParam as CheckoutSource;

    return { planKey, period, checkoutSource, currency };
  };

  // Fetch and validate the target plan
  const fetchAndValidatePlan = async ({ planKey }: { planKey: PlanKey }) => {
    const plans = session.sub?.plans || [];
    const targetPlan = plans.find(
      (plan: UsagePlanSchema) => plan.plan_key === planKey
    );

    if (!targetPlan) {
      throw new Error('Plan not found');
    }

    return targetPlan;
  };

  // Fire analytics tracking events
  const fireAnalyticsEvents = ({
    planKey,
    period,
    targetPlan,
  }: {
    planKey: PlanKey;
    period: SubscriptionPeriod;
    targetPlan: UsagePlanSchema;
  }) => {
    const usdPrice =
      period === SubscriptionPeriod.Annual
        ? targetPlan.annual_price_usd
        : targetPlan.monthly_price_usd;

    const axonItem = {
      item_variant_id: createAxonItemVariantIdForSubscription(planKey, period),
      item_id: targetPlan.plan_key,
      item_name: targetPlan.name,
      price: usdPrice,
      quantity: 1,
      item_category_id: AXON_ITEM_CATEGORY_ID,
    };

    publishAxonAddToCartEvent({
      currency: Currency.USD,
      value: usdPrice,
      items: [axonItem],
    });

    publishAxonBeginCheckoutEvent({
      currency: Currency.USD,
      value: usdPrice,
      items: [axonItem],
    });
  };

  // Create Stripe checkout session
  const createCheckoutSession = async ({
    planKey,
    period,
    checkoutSource,
    currency,
  }: {
    planKey: PlanKey;
    period: SubscriptionPeriod;
    checkoutSource: CheckoutSource;
    currency: Currency;
  }) => {
    const sproutAffiliateId = getSproutAffiliateIdForApi();

    const { data } = await apiClient.POST('/api/billing/create-session/', {
      body: {
        plan_key: planKey,
        period,
        checkout_source: checkoutSource,
        sprout_affiliate_id: sproutAffiliateId,
        currency,
      },
    });

    const checkoutSession = data as CheckoutSession;

    if (checkoutSession?.url) {
      return checkoutSession.url;
    } else {
      throw new Error('No checkout URL returned');
    }
  };

  useEffect(() => {
    const handleRedirectToSubscribe = async () => {
      // Prevent multiple executions - idempotency guard
      if (hasProcessedRef.current) return;
      if (!isLoaded || !session.isSubLoaded) return;

      if (!isSignedIn) {
        router.push('/');
        return;
      }

      // Validate URL parameters
      const { planKey, period, checkoutSource, currency } =
        validateAndExtractParams();
      if (!planKey || !period) {
        router.push('/account');
        return;
      }

      // Mark as processed to prevent duplicate executions
      hasProcessedRef.current = true;
      setIsProcessing(true);

      if (session.isSubscriber) {
        router.push('/account');
        return;
      }

      try {
        // Fetch plan details, track analytics events, create Stripe checkout session,
        // and redirect user to Stripe checkout page
        const targetPlan = await fetchAndValidatePlan({ planKey });
        fireAnalyticsEvents({ planKey, period, targetPlan });
        const checkoutUrl = await createCheckoutSession({
          planKey,
          period,
          checkoutSource,
          currency,
        });
        window.location.href = checkoutUrl;
      } catch (error) {
        console.error('Error processing subscription:', error);
        hasProcessedRef.current = false; // Reset on error to allow retry
        router.push('/account');
      }
    };

    handleRedirectToSubscribe();
  }, [
    isLoaded,
    isSignedIn,
    searchParams,
    router,
    clerkUser,
    apiClient,
    session,
    session.isSubLoaded,
    publishAxonAddToCartEvent,
    publishAxonBeginCheckoutEvent,
    getSproutAffiliateIdForApi,
  ]);

  return (
    <div className='flex min-h-screen w-full items-center justify-center'>
      <div className='flex flex-col items-center gap-4'>
        <SpinnerSVG className='h-12 w-12 fill-foreground-primary' />
        <p className='text-foreground-primary'>
          {isProcessing ? 'Preparing your subscription...' : 'Loading...'}
        </p>
      </div>
    </div>
  );
});

export default RedirectPageClient;
