import { useEffect, useRef, useState } from 'react';
import { Alert, Button, Group, Loader, Stack, Text, Title } from '@mantine/core';
import { IconAlertTriangle, IconArrowLeft } from '@tabler/icons-react';
import { useNavigate, useSearchParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { useApiMutation } from '@ema-platform/api';
import { useErrorHandler } from '@ema-platform/ui';
import { AuthShell } from '../components/AuthShell';
import { faydaSession, type FaydaResult } from '../utils/fayda-session';

/**
 * Where Fayda returns the applicant.
 *
 * It creates no account and holds no credentials — it hands the authorization
 * code to the API, stashes the normalised result, and sends the applicant back
 * to the signup form they started on.
 */
export function FaydaCallbackPage() {
  const navigate = useNavigate();
  const { t } = useTranslation();
  const [params] = useSearchParams();
  const { handleError } = useErrorHandler();
  const [error, setError] = useState<string | null>(null);
  const [callbackTrigger] = useApiMutation<FaydaResult>();

  // React 18 mounts effects twice in development, and the authorization code is
  // single-use — the second redemption would fail and show a spurious error.
  const redeemed = useRef(false);

  useEffect(() => {
    if (redeemed.current) return;
    redeemed.current = true;

    const code = params.get('code');
    const state = params.get('state');
    const providerError = params.get('error');
    const request = faydaSession.takeRequest();

    if (providerError) {
      setError(
        providerError === 'access_denied'
          ? t('fayda.cancelled', 'Fayda verification was cancelled. You can still sign up manually.')
          : t('fayda.rejected', 'Fayda could not verify your identity. Please try again.'),
      );
      return;
    }

    if (!code || !state) {
      setError(t('fayda.invalidCallback', 'This verification link is incomplete. Please start again.'));
      return;
    }

    if (!request) {
      setError(
        t('fayda.sessionLost', 'Your verification session has expired. Please start again.'),
      );
      return;
    }

    if (request.state !== state) {
      setError(t('fayda.stateMismatch', 'This verification could not be trusted. Please start again.'));
      return;
    }

    callbackTrigger({
      url: '/auth/register-with-fayda',
      method: 'POST',
      // `verify` returns the identity without creating an account — the
      // existing signup endpoint still does that.
      body: { action: 'verify', code, state, transactionToken: request.transactionToken },
    })
      .unwrap()
      .then((result) => {
        faydaSession.saveResult(result);
        // replace: the callback URL carries a spent code, so it must not come
        // back on Back.
        navigate('/signup', { replace: true });
      })
      .catch((err: unknown) => setError(handleError(err)));
    // Runs once on mount; the guard above makes that explicit.
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  return (
    <AuthShell
      brandTitle={t('fayda.brandTitle', 'Verifying with Fayda')}
      brandSubtitle={t('fayda.brandSubtitle', 'One moment while we confirm your identity.')}
    >
      <Stack gap="lg">
        {error ? (
          <>
            <Title order={2} fz={26}>
              {t('fayda.failedTitle', 'Verification incomplete')}
            </Title>
            <Alert
              variant="light"
              color="orange"
              icon={<IconAlertTriangle size={18} />}
            >
              {error}
            </Alert>
            <Group>
              <Button
                variant="light"
                leftSection={<IconArrowLeft size={18} />}
                onClick={() => navigate('/signup', { replace: true })}
              >
                {t('fayda.backToSignup', 'Back to sign up')}
              </Button>
            </Group>
          </>
        ) : (
          <Group gap="sm">
            <Loader size="sm" />
            <Text c="dimmed">{t('fayda.verifying', 'Verifying your Fayda identity…')}</Text>
          </Group>
        )}
      </Stack>
    </AuthShell>
  );
}
