import React, { useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';

import { InviteModal } from '../components/onboarding-chain/invite-modal';
import { LoopChain } from '../components/onboarding-chain/loop-chain';
import { OnboardingTopBar } from '../components/onboarding-chain/onboarding-topbar';
import { PartnerCodeModal } from '../components/onboarding-chain/partner-code-modal';
import { SetupPaths } from '../components/onboarding-chain/setup-paths';
import { MONO, SANS } from '../components/signup-mirror/theme';
import { Spinner } from '../components/ui/Spinner';
import { useAppStateContext } from '../context/user.data.context';
import { useCopilot } from '../context/copilot.context';
import { recomaze_ai_personalization_env } from '../env';
import { isSignupMirrorUser } from '../lib/signup-mirror/access';
import {
  LOOP_STEPS,
  resolveBrandName,
  SETUP_CALL_URL,
} from '../lib/onboarding-chain/content';
import {
  redeemPartnerCode,
  sendPartnerInvite,
} from '../service/partner/partner.service';
import { completeSignupMirror } from '../service/payment/payment.service';

const LATE_DELAY = 1.62;

const PageLoading = (): JSX.Element => (
  <div className="flex min-h-[60vh] items-center justify-center">
    <Spinner className="h-6 w-6 text-gray-400" />
  </div>
);

const OnboardingChain = (): JSX.Element => {
  const navigate = useNavigate();
  const { token, clientId, user } = useAppStateContext();
  const copilot = useCopilot();

  const [modal, setModal] = useState<null | 'invite' | 'agency'>(null);
  const [inviteSending, setInviteSending] = useState(false);
  const [inviteSent, setInviteSent] = useState(false);
  const [inviteSentTo, setInviteSentTo] = useState('');
  const [redeemApplying, setRedeemApplying] = useState(false);
  const [redeemError, setRedeemError] = useState<string | undefined>(undefined);

  useEffect(() => {
    if (!user) return;
    if (!isSignupMirrorUser(user)) {
      navigate('/dashboard', { replace: true });

      return;
    }
    if (user.signup_mirror_completed_at) {
      navigate('/dashboard', { replace: true });

      return;
    }
    if (user.launch_discount_status === 'ELIGIBLE') {
      navigate('/launch-discount', { replace: true });
    }
  }, [user, navigate]);

  const brand = resolveBrandName(
    user?.name,
    user?.domain ?? recomaze_ai_personalization_env?.domain
  );

  const complete = async (): Promise<void> => {
    try {
      await completeSignupMirror();
    } catch (error) {
      console.error(error);
    }
  };

  const bookSetup = (): void => {
    window.open(SETUP_CALL_URL, '_blank', 'noopener,noreferrer');
  };

  const runYourself = async (): Promise<void> => {
    await complete();
    // Close the copilot so the numbered setup rail on /company-id isn't hidden
    // behind the auto-opened panel (it opens for every brand-new merchant).
    copilot.close();
    navigate('/company-id');
  };

  const openCopilot = async (): Promise<void> => {
    await complete();
    copilot.open();
    navigate('/dashboard');
  };

  const invite = async (email: string, message: string): Promise<void> => {
    if (!token || inviteSending) return;
    setInviteSending(true);
    try {
      const res = await sendPartnerInvite({ email, message });
      if (res?.success) {
        setInviteSentTo(res.sent_to ?? email);
        setInviteSent(true);
        await complete();
      }
    } catch (inviteError) {
      console.error(inviteError);
    } finally {
      setInviteSending(false);
    }
  };

  const redeem = async (code: string): Promise<void> => {
    if (!token || redeemApplying) return;
    setRedeemApplying(true);
    setRedeemError(undefined);
    try {
      const res = await redeemPartnerCode({ code });
      if (res?.success) {
        await complete();
        navigate('/dashboard');

        return;
      }
      setRedeemError(res?.reason ?? res?.error ?? "That code didn't work.");
    } catch (redeemErr) {
      console.error(redeemErr);
      setRedeemError("That code didn't work.");
    } finally {
      setRedeemApplying(false);
    }
  };

  if (!token || !clientId) return <PageLoading />;

  return (
    <div
      className={`relative min-h-screen bg-[#f6f6f7] text-[#202223] ${SANS} text-[14px] leading-[1.55] antialiased selection:bg-[rgba(200,23,93,0.2)]`}
    >
      <div
        aria-hidden="true"
        className="absolute top-0 left-0 right-0 h-[520px] pointer-events-none"
        style={{
          background:
            'radial-gradient(46% 100% at 50% 0%, rgba(200,23,93,0.05), transparent 62%), radial-gradient(40% 90% at 50% 0%, rgba(123,63,228,0.04), transparent 66%)',
        }}
      />

      <OnboardingTopBar />

      <main className="relative z-[1] max-w-[1280px] mx-auto px-[clamp(20px,4vw,40px)] pt-[clamp(40px,6vh,64px)] pb-14">
        <div
          className={`text-center ${MONO} text-[11px] tracking-[0.22em] uppercase text-[#8c9196] mb-3.5`}
        >
          Welcome to Recomaze
        </div>
        <h1 className="text-[clamp(28px,4.2vw,44px)] font-bold tracking-[-0.02em] leading-[1.05] text-center text-[#202223] text-balance mb-4">
          Here&apos;s how Recomaze makes {brand} money
        </h1>
        <p className="text-[clamp(15px,1.5vw,17px)] leading-[1.5] text-[#6d7175] text-center max-w-[680px] mx-auto mb-[clamp(38px,5vh,52px)] text-pretty">
          One loop, five steps. Not more traffic:{' '}
          <strong className="text-[#202223] font-semibold">
            the traffic that brings your ideal customers
          </strong>
          . It starts with your Company ID, defined once, read by everything.
        </p>

        <div>
          <LoopChain steps={LOOP_STEPS} />

          <div
            data-rcm-anim
            style={{ animation: `rcm-fadeup .6s ease ${LATE_DELAY}s both` }}
          >
            <h2 className="text-center text-[clamp(22px,2.8vw,27px)] font-bold tracking-[-0.01em] text-[#202223] mt-[clamp(46px,6vh,60px)] mb-2">
              How do you want to run it?
            </h2>
            <p className="text-center text-[15px] text-[#6d7175] mb-7">
              Four ways to get set up. Pick the one that fits how you work.
            </p>

            <SetupPaths
              bookingEnabled
              onRunYourself={runYourself}
              onOpenCopilot={openCopilot}
              onBookSetup={bookSetup}
              onInvite={() => setModal('invite')}
              onAgency={() => setModal('agency')}
            />
          </div>
        </div>
      </main>

      {modal === 'invite' && (
        <InviteModal
          onSend={invite}
          onClose={() => setModal(null)}
          onDone={() => navigate('/dashboard')}
          sending={inviteSending}
          sent={inviteSent}
          sentTo={inviteSentTo}
        />
      )}

      {modal === 'agency' && (
        <PartnerCodeModal
          onApply={redeem}
          onClose={() => setModal(null)}
          onNoCode={() => setModal(null)}
          applying={redeemApplying}
          error={redeemError}
        />
      )}
    </div>
  );
};

export default OnboardingChain;
