import React, { useMemo, useRef, useEffect, useCallback, Suspense, lazy, useState } from "react";
import { useTranslation } from 'react-i18next';
import { Steps } from "@/components/ui/Steps";
import { Button } from "@/components/ui/button";
import { Progress } from "@/components/ui/progress";
import { CheckoutWizardProvider, useCheckoutWizard } from "./WizardContext";
import type { CheckoutPackage, CheckoutStepId, OAuthProfilePrefill } from "./types";
import { PackageStep } from "./steps/PackageStep";
import { AuthStep } from "./steps/AuthStep";
import { ConfirmationStep } from "./steps/ConfirmationStep";
import { useAnalytics } from '@/hooks/useAnalytics';
import { cn } from "@/lib/utils";
import toast from 'react-hot-toast';

const PaymentStep = lazy(() => import('./steps/PaymentStep').then((module) => ({ default: module.PaymentStep })));

interface CheckoutWizardProps {
  initialPackage: CheckoutPackage;
  packageOptions: CheckoutPackage[];
  privacyHtml: string;
  initialAuthUser?: {
    id: number;
    email: string;
    name?: string;
    pending_purchase?: boolean;
  } | null;
  initialStep?: CheckoutStepId;
  googleProfile?: OAuthProfilePrefill | null;
  facebookProfile?: OAuthProfilePrefill | null;
  paypal?: {
    client_id?: string | null;
    currency?: string | null;
    intent?: string | null;
    locale?: string | null;
  } | null;
}

const baseStepConfig: { id: CheckoutStepId; titleKey: string; descriptionKey: string; detailsKey: string }[] = [
  {
    id: "package",
    titleKey: 'checkout.package_step.title',
    descriptionKey: 'checkout.package_step.subtitle',
    detailsKey: 'checkout.package_step.description'
  },
  {
    id: "auth",
    titleKey: 'checkout.auth_step.title',
    descriptionKey: 'checkout.auth_step.subtitle',
    detailsKey: 'checkout.auth_step.description'
  },
  {
    id: "payment",
    titleKey: 'checkout.payment_step.title',
    descriptionKey: 'checkout.payment_step.subtitle',
    detailsKey: 'checkout.payment_step.description'
  },
  {
    id: "confirmation",
    titleKey: 'checkout.confirmation_step.title',
    descriptionKey: 'checkout.confirmation_step.subtitle',
    detailsKey: 'checkout.confirmation_step.description'
  },
];

const PaymentStepFallback: React.FC = () => (
  <div className="rounded-lg border bg-card p-6 shadow-sm">
    <div className="mb-4 h-4 w-52 animate-pulse rounded bg-muted" />
    <div className="h-10 w-full animate-pulse rounded bg-muted" />
  </div>
);

const WizardBody: React.FC<{
  privacyHtml: string;
  prefillProfile?: OAuthProfilePrefill | null;
  onClearPrefill?: () => void;
}> = ({ privacyHtml, prefillProfile, onClearPrefill }) => {
  const primaryCtaClassName = "min-w-[160px] disabled:bg-muted disabled:text-muted-foreground disabled:hover:bg-muted disabled:hover:text-muted-foreground";
  const { t } = useTranslation('marketing');
  const {
    currentStep,
    nextStep,
    previousStep,
    selectedPackage,
    authUser,
    isAuthenticated,
    paymentCompleted,
    goToStep,
  } = useCheckoutWizard();
  const progressRef = useRef<HTMLDivElement | null>(null);
  const hasMountedRef = useRef(false);
  const { trackEvent } = useAnalytics();

  const stepConfig = useMemo(() =>
    baseStepConfig.map(step => ({
      id: step.id,
      title: t(step.titleKey),
      description: t(step.descriptionKey),
      details: t(step.detailsKey),
    })),
    [t]
  );

  const currentIndex = useMemo(
    () => stepConfig.findIndex((step) => step.id === currentStep),
    [currentStep, stepConfig]
  );
  const progress = useMemo(() => {
    if (currentIndex < 0) {
      return 0;
    }
    return (currentIndex / (stepConfig.length - 1)) * 100;
  }, [currentIndex, stepConfig]);

  useEffect(() => {
    trackEvent({
      category: 'marketing_checkout',
      action: 'step_view',
      name: currentStep,
    });
  }, [currentStep, trackEvent]);

  useEffect(() => {
    if (currentStep === 'payment' && !isAuthenticated) {
      toast.error(t('checkout.payment_step.auth_required'));
      goToStep('auth');
    }
  }, [currentStep, goToStep, isAuthenticated, t]);

  useEffect(() => {
    if (typeof window === 'undefined' || !progressRef.current) {
      return;
    }

    if (!hasMountedRef.current) {
      hasMountedRef.current = true;
      return;
    }

    const element = progressRef.current;
    const rect = element.getBoundingClientRect();
    const scrollTop = window.scrollY + rect.top - 16; // slightly above the progress bar

    window.scrollTo({
      top: Math.max(scrollTop, 0),
      behavior: 'smooth',
    });
  }, [currentStep]);

  const atLastStep = currentIndex >= stepConfig.length - 1;

  const canProceedToNextStep = useMemo(() => {
    if (atLastStep) {
      return false;
    }

    if (currentStep === 'package') {
      return Boolean(selectedPackage);
    }

    if (currentStep === 'auth') {
      return Boolean(isAuthenticated && authUser);
    }

    if (currentStep === 'payment') {
      return paymentCompleted;
    }

    return true;
  }, [atLastStep, authUser, currentStep, isAuthenticated, paymentCompleted, selectedPackage]);

  const shouldShowNextButton = useMemo(
    () => currentStep !== 'confirmation' && currentStep !== 'payment',
    [currentStep]
  );
  const highlightNextCta = currentStep === 'payment' && paymentCompleted;

  const handleNext = useCallback(() => {
    if (!canProceedToNextStep) {
      return;
    }

    const targetStep = stepConfig[currentIndex + 1]?.id ?? 'end';
    trackEvent({
      category: 'marketing_checkout',
      action: 'step_next',
      name: `${currentStep}->${targetStep}`,
    });
    nextStep();
  }, [canProceedToNextStep, currentIndex, currentStep, nextStep, stepConfig, trackEvent]);

  const handlePrevious = useCallback(() => {
    const targetStep = stepConfig[currentIndex - 1]?.id ?? 'start';
    trackEvent({
      category: 'marketing_checkout',
      action: 'step_previous',
      name: `${currentStep}->${targetStep}`,
    });
    previousStep();
  }, [currentIndex, currentStep, previousStep, stepConfig, trackEvent]);

  const handleViewProfile = useCallback(() => {
    window.location.href = '/settings/profile';
  }, []);

  const handleGoToAdmin = useCallback(() => {
    window.location.href = '/event-admin';
  }, []);

  const primaryCta = useMemo(() => {
    if (currentStep === 'confirmation') {
      return {
        label: t('checkout.confirmation_step.to_admin'),
        onClick: handleGoToAdmin,
        disabled: false,
      };
    }

    if (!shouldShowNextButton) {
      return null;
    }

    return {
      label: t('checkout.next'),
      onClick: handleNext,
      disabled: !canProceedToNextStep,
    };
  }, [currentStep, handleGoToAdmin, handleNext, shouldShowNextButton, t, canProceedToNextStep]);
  const ctaClassName = cn(primaryCtaClassName, highlightNextCta && 'animate-pulse ring-2 ring-primary/50 ring-offset-2 ring-offset-background');

  return (
    <div className="space-y-8">
      {primaryCta && (
        <div className="flex justify-end">
          <Button
            size="lg"
            className={ctaClassName}
            onClick={primaryCta.onClick}
            disabled={primaryCta.disabled}
          >
            {primaryCta.label}
          </Button>
        </div>
      )}

      <div ref={progressRef} className="space-y-4">
        <Progress value={progress} />
        <Steps steps={stepConfig} currentStep={currentIndex >= 0 ? currentIndex : 0} />
      </div>

      <div className="space-y-6">
        {currentStep === "package" && <PackageStep />}
        {currentStep === "auth" && (
          <AuthStep
            privacyHtml={privacyHtml}
            prefill={prefillProfile ?? undefined}
            onClearPrefill={onClearPrefill}
          />
        )}
        {currentStep === "payment" && (
          <Suspense fallback={<PaymentStepFallback />}>
            <PaymentStep />
          </Suspense>
        )}
        {currentStep === "confirmation" && (
          <ConfirmationStep onViewProfile={handleViewProfile} onGoToAdmin={handleGoToAdmin} />
        )}
      </div>

      <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
        <Button variant="ghost" onClick={handlePrevious} disabled={currentIndex <= 0}>
          {t('checkout.back')}
        </Button>
        {primaryCta ? (
          <Button
            size="lg"
            className={ctaClassName}
            onClick={primaryCta.onClick}
            disabled={primaryCta.disabled}
          >
            {primaryCta.label}
          </Button>
        ) : (
          <div className="h-10 min-w-[128px]" aria-hidden="true" />
        )}
      </div>
    </div>
  );
};

export const CheckoutWizard: React.FC<CheckoutWizardProps> = ({
  initialPackage,
  packageOptions,
  privacyHtml,
  initialAuthUser,
  initialStep,
  googleProfile,
  facebookProfile,
  paypal,
}) => {
  const [storedGoogleProfile, setStoredGoogleProfile] = useState<OAuthProfilePrefill | null>(() => {
    if (typeof window === 'undefined') {
      return null;
    }

    const raw = window.localStorage.getItem('checkout-google-profile');
    if (!raw) {
      return null;
    }

    try {
      return JSON.parse(raw) as OAuthProfilePrefill;
    } catch (error) {
      console.warn('Failed to parse checkout google profile from storage', error);
      window.localStorage.removeItem('checkout-google-profile');
      return null;
    }
  });

  useEffect(() => {
    if (!googleProfile) {
      return;
    }

    setStoredGoogleProfile(googleProfile);

    if (typeof window !== 'undefined') {
      window.localStorage.setItem('checkout-google-profile', JSON.stringify(googleProfile));
    }
  }, [googleProfile]);

  const clearStoredGoogleProfile = useCallback(() => {
    setStoredGoogleProfile(null);
    if (typeof window !== 'undefined') {
      window.localStorage.removeItem('checkout-google-profile');
    }
  }, []);

  const [storedFacebookProfile, setStoredFacebookProfile] = useState<OAuthProfilePrefill | null>(() => {
    if (typeof window === 'undefined') {
      return null;
    }

    const raw = window.localStorage.getItem('checkout-facebook-profile');
    if (!raw) {
      return null;
    }

    try {
      return JSON.parse(raw) as OAuthProfilePrefill;
    } catch (error) {
      console.warn('Failed to parse checkout facebook profile from storage', error);
      window.localStorage.removeItem('checkout-facebook-profile');
      return null;
    }
  });

  useEffect(() => {
    if (!facebookProfile) {
      return;
    }

    setStoredFacebookProfile(facebookProfile);

    if (typeof window !== 'undefined') {
      window.localStorage.setItem('checkout-facebook-profile', JSON.stringify(facebookProfile));
    }
  }, [facebookProfile]);

  const clearStoredFacebookProfile = useCallback(() => {
    setStoredFacebookProfile(null);
    if (typeof window !== 'undefined') {
      window.localStorage.removeItem('checkout-facebook-profile');
    }
  }, []);

  const clearStoredProfiles = useCallback(() => {
    clearStoredGoogleProfile();
    clearStoredFacebookProfile();
  }, [clearStoredFacebookProfile, clearStoredGoogleProfile]);

  const effectiveProfile = facebookProfile ?? storedFacebookProfile ?? googleProfile ?? storedGoogleProfile;

  return (
    <CheckoutWizardProvider
      initialPackage={initialPackage}
      packageOptions={packageOptions}
      initialStep={initialStep}
      initialAuthUser={initialAuthUser ?? undefined}
      initialIsAuthenticated={Boolean(initialAuthUser)}
      paypal={paypal ?? null}
    >
      <WizardBody
        privacyHtml={privacyHtml}
        prefillProfile={effectiveProfile}
        onClearPrefill={clearStoredProfiles}
      />
    </CheckoutWizardProvider>
  );
};
