import { useCallback, useMemo, useState } from 'react';

import type { MappedUser } from '~/src/lib/songwhipApi/users/types';

import { ACCOUNT_COOKIE_NAME } from '~/lib/constants';
import { setClientCookie } from '~/lib/utils/cookie';
import navigateWindow from '~/lib/utils/navigateWindow';
import AuthGuard from '~/src/components/AuthGuard';
import Box from '~/src/components/Box';
import ErrorText from '~/src/components/ErrorText';
import FadeOnMount from '~/src/components/FadeOnMount';
import { InputLabelDescription } from '~/src/components/InputLabel';
import ListItem from '~/src/components/ListItem';
import Page from '~/src/components/Page';
import PageLoading from '~/src/components/PageLoading';
import PageMetadata from '~/src/components/PageMetadata';
import SearchTextInput from '~/src/components/SearchTextInput';
import Text from '~/src/components/Text';
import useFetchAccounts from '~/src/hooks/useFetchAccounts';
import useTheme from '~/src/hooks/useTheme';
import { useI18n } from '~/src/lib/i18n';
import { useAppRouter } from '~/src/lib/router2';
import { useTracker } from '~/src/lib/tracker/useTracker';
import { filterAndSortAccounts } from './utils';

/**
 * Orchard Employees will be redirected to this page when opening the app
 * in order to select the Account they want to emulate.
 * Once an Account is selected, the ID will be stored in a client cookie
 * and the user will be redirected to the homepage.
 */
const PickAccountPage = ({ user }: { user: MappedUser }) => {
  const theme = useTheme();
  const { t } = useI18n('pickAccount');
  const { trackEvent } = useTracker();
  const router = useAppRouter();

  const [inputValue, setInputValue] = useState('');
  const [isUpserting, setIsUpserting] = useState(false);

  const {
    result: accounts,
    isLoading,
    error,
  } = useFetchAccounts({ userId: user.id }, [user.id]);

  // The API returns the full account list with no filtering/sorting, so we
  // filter (by name) and sort (alphabetically by name) entirely client-side.
  const filteredAccounts = useMemo(
    () => filterAndSortAccounts(accounts, inputValue),
    [accounts, inputValue]
  );

  const noResults = filteredAccounts && filteredAccounts.length === 0;

  const onInputEnd = useCallback(({ value }) => {
    setInputValue(value);

    trackEvent({
      type: 'search',
      id: 'pick-account-page:search-orchard-labels',
      term: value,
    });
  }, []);

  const renderItems = useCallback(() => {
    if (error) {
      return (
        <Box spacing="2.4rem" coverParent centerContent>
          <ErrorText error={error} size="2.4rem" centered isParagraph />
        </Box>
      );
    }

    if (noResults) {
      return (
        <Text centered isParagraph color="#ccc" size="1.5rem">
          {t('noOrchardLabelsFound')}
        </Text>
      );
    }

    return filteredAccounts?.map((account) => (
      <ListItem
        testId="accountListItem"
        key={`${account.id}`}
        title={account.name}
        subtitle={
          account.labelSubaccountId
            ? `Subaccount • ${account.labelSubaccountId}`
            : `Label • ${account.labelVendorId}`
        }
        height="6rem"
        onClick={async () => {
          setIsUpserting(true);

          try {
            // Store the Account ID in a persistent client cookie (1 year).
            // This way the user doesn't have to select it again when the session expires.
            setClientCookie(ACCOUNT_COOKIE_NAME, account.id, 365);

            const { redirectPath = '/' } = router.getAsQuery();

            navigateWindow(`${window.location.origin}${redirectPath}`);
          } catch {
            setIsUpserting(false);
          }
        }}
      />
    ));
  }, [error, noResults, filteredAccounts]);

  const renderPage = useCallback(() => {
    if (isUpserting) {
      return <PageLoading />;
    }

    return (
      <Box maxWidth="50rem" padding="1rem 2rem 2rem" isCentered>
        <FadeOnMount>
          <div>
            <SearchTextInput
              isLoading={isLoading}
              centerText
              testId="orchardLabelSearchInput"
              height="5rem"
              placeholder={t('orchardLabelSearchPlaceholder')}
              onInputEnd={onInputEnd}
              debounceTimeout={300}
              autoFocus
            />
            <InputLabelDescription
              value={t('helpText')}
              centered
              margin="1rem 0 0"
            />
            <Box margin="3rem 0 0">{renderItems()}</Box>
          </div>
        </FadeOnMount>
      </Box>
    );
  }, [isUpserting, isLoading, filteredAccounts, error, inputValue]);

  return (
    <Page
      withGradient
      withMenuButton={false}
      withBackButton={false}
      testId="pickAccountPage"
      renderHeaderContent={() => (
        <Text size="1.5rem" isBold color={theme.textColor40}>
          {t('pageTitle')}
        </Text>
      )}
      contentStyle={{
        paddingTop: '6rem',
      }}
    >
      <AuthGuard render={renderPage} />
      <PageMetadata title={t('pageTitle')} />
    </Page>
  );
};

export default PickAccountPage;
