import { useSearchParams } from 'next/navigation';
import { useEffect, useMemo, useRef, useState } from 'react';
import { twMerge } from 'tailwind-merge';
import { useResizeObserver } from 'usehooks-ts';

import { DEFAULT_CURRENCY } from '@/app/(root)/account/constants';
import RadioGroupWithBadges from '@/components/RadioGroupWithBadges/RadioGroupWithBadges';
import { AuraSubscriptionCard } from '@/components/card/AuraSubscriptionCard';
import { AXON_ITEM_CATEGORY_ID } from '@/components/ga4/constants';
import {
  createAxonItemVariantIdForSubscription,
  useAxon,
} from '@/components/ga4/useAxon';
import { useDefaultBillingPeriod } from '@/hooks/useDefaultBillingPeriod';
import { useEligibleDiscounts } from '@/hooks/useEligibleDiscounts';
import { CHECKOUT_SOURCE } from '@/lib/checkoutSource';
import logWebUserEvent from '@/logging/logWebUserEvent';
import {
  CtaButtons,
  PlanKey,
  SubscriptionInfo,
  UsagePlanDescription,
  UsagePlanSchema,
} from '@/state/sessionStore';
import { SubscriptionPeriod } from '@/utils/session';

import { ScrollablePlans } from './ScrollablePlans';

const { Annual: ANNUAL, Monthly: MONTHLY } = SubscriptionPeriod;

interface SplashPagePlansProps {
  plans: UsagePlanSchema[];
  currentSubscription: SubscriptionInfo | null;
  usagePlanDescriptions: Record<string, UsagePlanDescription>;
  ctaButtons?: CtaButtons | null;
  toggleMonthly?: string;
  toggleYearly?: string;
}

export const SplashPagePlans = ({
  plans,
  currentSubscription,
  usagePlanDescriptions,
  ctaButtons,
  toggleMonthly = 'Monthly',
  toggleYearly = 'Yearly',
}: SplashPagePlansProps) => {
  const urlParams = useSearchParams();
  const { publishViewItemEvent: publishAxonViewItemEvent } = useAxon();
  const { data: eligibleDiscountsResult } = useEligibleDiscounts();
  const defaultPeriod = useDefaultBillingPeriod();

  const urlPeriod = urlParams.get('period') as SubscriptionPeriod;
  const [period, setPeriod] = useState<SubscriptionPeriod>(
    urlPeriod || defaultPeriod
  );

  // Update period when defaultPeriod changes (e.g., when Statsig loads)
  useEffect(() => {
    // Only update if there's no URL parameter override
    if (!urlPeriod) {
      setPeriod(defaultPeriod);
    }
  }, [defaultPeriod, urlPeriod]);

  useEffect(() => {
    const proPlan = plans.find((plan) => plan.plan_key === PlanKey.Pro);

    if (!proPlan || proPlan.monthly_price_usd === 0) return;

    const price =
      period === ANNUAL ? proPlan.annual_price_usd : proPlan.monthly_price_usd;

    const items = [
      {
        item_variant_id: createAxonItemVariantIdForSubscription(
          proPlan.plan_key,
          period
        ),
        item_id: proPlan.plan_key,
        item_name: proPlan.name,
        price,
        quantity: 1,
        item_category_id: AXON_ITEM_CATEGORY_ID,
      },
    ];

    publishAxonViewItemEvent({
      currency: 'USD',
      value: price,
      items,
    });
  }, [publishAxonViewItemEvent, period, plans]);

  const getPriceForPlan = (plan: UsagePlanSchema, period: string) => {
    if (period === ANNUAL) {
      return plan.annual_price_usd / 12;
    }
    return plan.monthly_price_usd;
  };

  const sortedPlans = useMemo<UsagePlanSchema[]>(() => {
    if (!plans) return [];

    return [...plans].sort((a, b) => {
      return a.monthly_price_usd - b.monthly_price_usd;
    });
  }, [plans]);

  const synchronizeDescriptionHeights = () => {
    const descriptions = document.querySelectorAll(
      '[data-description]'
    ) as NodeListOf<HTMLElement>;
    if (descriptions.length === 0) return;

    descriptions.forEach((desc: HTMLElement) => {
      desc.style.minHeight = 'auto';
      desc.style.height = 'auto';
    });

    const maxHeight = Math.max(
      ...Array.from(descriptions).map((desc: HTMLElement) => desc.scrollHeight)
    );

    descriptions.forEach((desc: HTMLElement) => {
      desc.style.minHeight = `${maxHeight}px`;
    });
  };

  const containerRef = useRef<HTMLDivElement>(null);
  useResizeObserver({
    ref: containerRef as React.RefObject<HTMLDivElement>,
    onResize: () => {
      requestAnimationFrame(() => {
        synchronizeDescriptionHeights();
      });
    },
  });

  useEffect(() => {
    const timer = setTimeout(() => {
      synchronizeDescriptionHeights();
    }, 10);

    return () => clearTimeout(timer);
  }, [sortedPlans, usagePlanDescriptions, period]);

  const getFeatureDescriptions = (plan: UsagePlanSchema) => {
    let dynamicFeatures =
      usagePlanDescriptions[plan.plan_key]?.feature_descriptions || [];

    if (!dynamicFeatures.length) {
      const features = plan.features.split('\n') || [];
      dynamicFeatures = features.map((feature: string) => ({
        text: feature,
        type: 'plus',
      }));
    }

    return dynamicFeatures;
  };

  const handlePeriodChange = (value: string) => {
    const newPeriod = value as SubscriptionPeriod;
    logWebUserEvent({
      actionName: 'SubscriptionPeriodTabClicked',
      context: {
        period: newPeriod,
        pageUrl: window.location.pathname,
      },
      componentContext: '',
    });
    setPeriod(newPeriod);
  };

  const handleSetPeriodAnnual = () => {
    logWebUserEvent({
      actionName: 'SaveByPayingAnnuallyLinkClicked',
      context: {
        pageUrl: window.location.pathname,
      },
    });
    setPeriod(ANNUAL);
  };

  const gridClassName = twMerge(
    'w-full gap-6 grid grid-cols-1 [grid-auto-rows:1fr] items-start',
    sortedPlans.length >= 2 && 'min-[600px]:grid-cols-2',
    sortedPlans.length >= 3 && 'min-[1024px]:grid-cols-3',
    sortedPlans.length >= 4 && 'min-[1200px]:grid-cols-4'
  );

  return (
    <div className='mt-4 flex w-full flex-col items-center gap-10 overflow-visible'>
      <RadioGroupWithBadges
        value={period}
        options={[
          { label: toggleMonthly, value: MONTHLY },
          {
            label: toggleYearly,
            value: ANNUAL,
            badge: {
              text: 'save 20%',
              className: 'bg-white/20 text-white/90',
            },
          },
        ]}
        onChange={handlePeriodChange}
      />

      <div className='w-full overflow-visible lg:hidden'>
        <ScrollablePlans
          plans={sortedPlans}
          period={period}
          currentSubscription={currentSubscription}
          usagePlanDescriptions={usagePlanDescriptions}
          ctaButtons={ctaButtons}
          getPriceForPlan={getPriceForPlan}
          getFeatureDescriptions={getFeatureDescriptions}
          handleSetPeriodAnnual={handleSetPeriodAnnual}
        />
      </div>

      <div ref={containerRef} className={`${gridClassName} hidden lg:grid`}>
        {sortedPlans?.map((plan: UsagePlanSchema) => (
          <AuraSubscriptionCard
            key={plan.id}
            plan={plan}
            price={getPriceForPlan(plan, period)}
            priceBeforeDiscount={plan.monthly_price_usd}
            period={period}
            billed={period === ANNUAL ? 'yearly' : 'monthly'}
            features={getFeatureDescriptions(plan)}
            currentSubscription={currentSubscription}
            setPeriodAnnual={handleSetPeriodAnnual}
            planDescription={usagePlanDescriptions[plan.plan_key]}
            ctaButtons={ctaButtons}
            checkoutSource={CHECKOUT_SOURCE.SPLASH_PAGE}
            selectedCurrency={DEFAULT_CURRENCY}
            discountDetails={
              eligibleDiscountsResult?.eligible_discounts[plan.plan_key]?.[
                period
              ]
            }
          />
        ))}
      </div>
    </div>
  );
};
