import React, { useContext, useEffect, useState } from 'react';
import { useNavigate, useSearchParams, Link } from 'react-router-dom';
import { AxiosResponse } from 'axios';
import styled from 'styled-components';
import { applyAccessToken, axiosInstance } from '../../../axiosApi';
import { setTokens } from '../../auth/tokenStorage';
import { oauthErrorMessage } from '../../auth/sso';
import { AuthContext } from '../../contexts/AuthContext';
import { AccountContext } from '../../contexts/AccountContext';
import { Account, AccountType } from '../../data';
import ParticleBackground from '../../components/ParticleBackground/ParticleBackground';
import { AnalyticsEvents, identifyAccount, trackEvent } from '../../utils/analytics';
import { checkoutReturnUrls } from '../../utils/finance';
import { isNativePlatform } from '../../platform/nativePlatform';
import { logInRevenueCat, purchasePlan } from '../../utils/revenueCat';

const PageContainer = styled.div`
  position: relative;
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  color: #fff;
  font-family: 'Inter', sans-serif;
`;

const ContentWrapper = styled.div`
  flex: 1;
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 5;
  padding: 2rem;
`;

const GlassCard = styled.div`
  background: rgba(0, 0, 0, 0.4);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 1rem;
  padding: 3rem;
  width: 100%;
  max-width: 450px;
  box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.37);
  display: flex;
  flex-direction: column;
  align-items: center;
`;

const CardTitle = styled.h2`
  font-size: 2rem;
  margin-bottom: 1rem;
  color: #fff;
  text-align: center;
`;

const CardSubtitle = styled.p`
  color: rgba(255, 255, 255, 0.65);
  text-align: center;
  margin-bottom: 1.5rem;
  font-size: 0.95rem;
`;

const ErrorMessage = styled.div`
  color: #ff6b6b;
  margin-bottom: 1rem;
  text-align: center;
  background: rgba(255, 107, 107, 0.1);
  padding: 0.5rem;
  border-radius: 0.5rem;
  width: 100%;
`;

const NavLink = styled(Link)`
  color: rgba(255, 255, 255, 0.6);
  margin-top: 1rem;
  font-size: 0.9rem;
  text-decoration: none;

  &:hover {
    color: #fff;
    text-decoration: underline;
  }
`;

const AuthCallback = (): JSX.Element => {
  const { setAuthentication, setNeedsNewPassword } = useContext(AuthContext);
  const { setAccount } = useContext(AccountContext);
  const navigate = useNavigate();
  const [searchParams] = useSearchParams();
  const [errorMessage, setErrorMessage] = useState('');
  const [statusText, setStatusText] = useState('Completing sign-in…');

  useEffect(() => {
    let cancelled = false;

    const run = async () => {
      const error = searchParams.get('error');
      if (error) {
        trackEvent(AnalyticsEvents.LOGIN_FAILED, { method: 'sso', error });
        setErrorMessage(
          oauthErrorMessage(error, searchParams.get('error_description'))
        );
        setStatusText('Sign-in failed');
        return;
      }

      // Drive-link flows (#83/#84) redirect here already authenticated — just
      // bounce to Documents with a flag so it can show a success banner.
      if (searchParams.get('drive_connected') === '1') {
        navigate('/document_storage/?drive_connected=1', { replace: true });
        return;
      }

      const access = searchParams.get('access');
      const refresh = searchParams.get('refresh');
      const needsCheckout = searchParams.get('needs_checkout') === '1';
      const isNewUser = searchParams.get('created') === '1';

      if (!access || !refresh) {
        trackEvent(AnalyticsEvents.LOGIN_FAILED, { method: 'sso', reason: 'missing_tokens' });
        setErrorMessage('Missing sign-in tokens. Please try again.');
        setStatusText('Sign-in failed');
        return;
      }

      try {
        await setTokens(access, refresh);
        applyAccessToken(access);

        const get_user_response: AxiosResponse<AccountType> = await axiosInstance.get(
          '/user/get/'
        );
        if (cancelled) {
          return;
        }

        const account = new Account({
          id: get_user_response.data.id,
          email: get_user_response.data.email,
          first_name: get_user_response.data.first_name,
          last_name: get_user_response.data.last_name,
          is_company_manager: get_user_response.data.is_company_manager,
          has_signed_tos: get_user_response.data.has_signed_tos,
          company: {
            id: get_user_response.data.company?.id,
            name: get_user_response.data.company?.name,
            state: get_user_response.data.company?.state,
            zipcode: get_user_response.data.company?.zipcode,
            address: get_user_response.data.company?.address,
          },
        });
        setAccount(account);
        setAuthentication(true);
        setNeedsNewPassword(get_user_response.data.has_usable_password);

        if (isNewUser) {
          trackEvent(AnalyticsEvents.SIGNUP_SUCCESS, { method: 'sso' });
        } else {
          trackEvent(AnalyticsEvents.LOGIN_SUCCESS, { method: 'sso' });
        }
        identifyAccount(account);
        void Promise.resolve(logInRevenueCat(account)).catch((err) =>
          console.warn('RevenueCat logIn', err)
        );

        if (needsCheckout) {
          if (isNativePlatform()) {
            setStatusText('Starting store purchase…');
            try {
              trackEvent(AnalyticsEvents.CHECKOUT_STARTED, { source: 'sso_signup_native' });
              await purchasePlan();
            } catch (purchaseError) {
              console.warn('RevenueCat purchase after SSO signup', purchaseError);
            }
            navigate('/account/', { replace: true });
            return;
          }

          setStatusText('Starting checkout…');
          const { success_url, cancel_url } = checkoutReturnUrls();
          trackEvent(AnalyticsEvents.CHECKOUT_STARTED, { source: 'sso_signup' });
          const checkoutResponse = await axiosInstance.post('/monetization/checkout/', {
            success_url,
            cancel_url,
          });
          const checkoutUrl = checkoutResponse.data?.checkout_url;
          if (!checkoutUrl) {
            setErrorMessage(
              'Account created, but checkout could not be started. Try signing in.'
            );
            setStatusText('Checkout unavailable');
            return;
          }
          window.location.assign(checkoutUrl);
          return;
        }

        if (account.has_signed_tos) {
          navigate('/', { replace: true });
        } else {
          navigate('/terms_of_service/', { replace: true });
        }
      } catch (err) {
        console.log(err);
        if (!cancelled) {
          trackEvent(AnalyticsEvents.LOGIN_FAILED, { method: 'sso' });
          setErrorMessage('Could not finish sign-in. Try again.');
          setStatusText('Sign-in failed');
        }
      }
    };

    run();
    return () => {
      cancelled = true;
    };
  }, [
    searchParams,
    navigate,
    setAccount,
    setAuthentication,
    setNeedsNewPassword,
  ]);

  return (
    <PageContainer>
      <ParticleBackground />
      <ContentWrapper>
        <GlassCard>
          <CardTitle>Sign In</CardTitle>
          <CardSubtitle>{statusText}</CardSubtitle>
          {errorMessage && <ErrorMessage>{errorMessage}</ErrorMessage>}
          {errorMessage && <NavLink to="/signin/">Back to Sign In</NavLink>}
        </GlassCard>
      </ContentWrapper>
    </PageContainer>
  );
};

export default AuthCallback;
