import { useMemo, useState } from 'react';
import { Helmet } from 'react-helmet-async';
import { useQuery } from 'react-query';

import Stack from '@material-hu/mui/Stack';

import * as HuAuth from '@material-hu/components/composed-components/auth';

import adminBanner from 'src/assets/login-banner.webp';
import useGeneralError from 'src/hooks/useGeneralError';
import useHuGoTheme from 'src/hooks/useHuGoTheme';
import useStateLocation from 'src/hooks/useStateLocation';
import {
  SendSMS,
  CheckCode,
  PhoneNotUpdated,
  MaxTries,
  Loading,
} from 'src/pages/authentication/LoginOTP/components';
import { loginKeys } from 'src/pages/authentication/queries';
import { getOTP } from 'src/services/authService';
import { OTPChannels, OTPErrors, OTPState } from 'src/types/login';
import { formatTitle } from 'src/utils/helmetUtils';
import { useLokaliseTranslation } from 'src/utils/i18n';

const LoginOTP = () => {
  const [step, setStep] = useState<number>(0);
  const [error, setError] = useState<OTPErrors | null>(null);
  const [selectedChannel, setSelectedChannel] = useState<OTPChannels | null>(
    null,
  );

  const { t } = useLokaliseTranslation('authentication');
  const showGeneralError = useGeneralError();
  const state = useStateLocation<OTPState>();
  const HugoThemeProvider = useHuGoTheme();

  const handleNext = () => setStep(step + 1);

  const handleRetry = () => {
    setStep(0);
    setError(null);
  };

  const handleError = (err: OTPErrors) => {
    setError(err);
  };

  const { data: otpData, isLoading } = useQuery(
    loginKeys.otp.detail(state?.instance?.id, state?.employeeInternalId),
    () => getOTP(state?.instance?.id, state?.employeeInternalId),
    {
      select: r => r?.data,
      onError: (err: any) => {
        if (
          [OTPErrors.PHONE_NOT_FOUND, OTPErrors.INVALID_PHONE].includes(
            err?.response?.data?.code,
          )
        ) {
          handleError(err?.response?.data?.code);
          return;
        }

        showGeneralError(err, t('GENERAL:ERROR'));
      },
      onSuccess: response => {
        if (response?.length <= 0) {
          handleError(OTPErrors.PHONE_NOT_FOUND);
        }
      },
    },
  );

  const phoneNumber = useMemo(
    () =>
      otpData?.find(val =>
        [OTPChannels.WHATSAPP, OTPChannels.SMS].includes(val.channel),
      )?.receiver,
    [otpData],
  );

  const channels = useMemo(() => otpData?.map(val => val.channel), [otpData]);

  const steps = [
    <SendSMS
      key="send-sms"
      receiver={phoneNumber || ''}
      channels={channels!}
      onSuccess={handleNext}
      onError={handleError}
      setSelectedChannel={setSelectedChannel}
      selectedChannel={selectedChannel}
    />,
    <CheckCode
      key="check-code"
      receiver={phoneNumber || ''}
      channels={channels!}
      selectedChannel={selectedChannel!}
      onError={handleError}
      onSuccess={newSelectedChannel => setSelectedChannel(newSelectedChannel)}
    />,
  ];

  const errors = {
    [OTPErrors.INVALID_PHONE]: <PhoneNotUpdated />,
    [OTPErrors.PHONE_NOT_FOUND]: <PhoneNotUpdated />,
    [OTPErrors.MAX_TRIES]: <MaxTries onRetry={handleRetry} />,
  };

  return (
    <>
      <Helmet>
        <title>{formatTitle(t('LOGIN'))}</title>
      </Helmet>
      <HugoThemeProvider>
        {!error && (
          <HuAuth.LoginLayout
            banner={{
              src: adminBanner,
              styles: {
                width: '85%',
              },
            }}
          >
            <Stack
              sx={{
                width: '100%',
                height: '100%',
                justifyContent: 'center',
                alignItems: 'center',
              }}
            >
              {isLoading && <Loading />}
              {!isLoading && !error && steps[step]}
            </Stack>
          </HuAuth.LoginLayout>
        )}
        {!!error && errors[error as keyof typeof errors]}
      </HugoThemeProvider>
    </>
  );
};

export default LoginOTP;
