import { useEffect } from 'react';
import type { FC } from 'react';

import { defineMessage, FormattedMessage } from 'react-intl';

import { useDebouncedCallback } from 'use-debounce';

import {
  expandFollowing,
  fetchFollowing,
} from '@/flavours/glitch/actions/accounts';
import { useAccount } from '@/flavours/glitch/hooks/useAccount';
import { useAccountId } from '@/flavours/glitch/hooks/useAccountId';
import { useRelationship } from '@/flavours/glitch/hooks/useRelationship';
import { selectUserListWithoutMe } from '@/flavours/glitch/selectors/user_lists';
import { useAppDispatch, useAppSelector } from '@/flavours/glitch/store';

import type { EmptyMessageProps } from '../followers/components/empty';
import { BaseEmptyMessage } from '../followers/components/empty';
import { AccountListHeader } from '../followers/components/header';
import { AccountList } from '../followers/components/list';

import { RemoteHint } from './components/remote';

const titleText = defineMessage({
  id: 'following.title',
  defaultMessage: 'Followed by {name}',
});

const Followers: FC = () => {
  const accountId = useAccountId();
  const account = useAccount(accountId);
  const currentAccountId = useAppSelector(
    (state) => (state.meta.get('me') as string | null) ?? null,
  );
  const followingList = useAppSelector((state) =>
    selectUserListWithoutMe(state, 'following', accountId),
  );

  const dispatch = useAppDispatch();
  useEffect(() => {
    if (!followingList && accountId) {
      dispatch(fetchFollowing(accountId));
    }
  }, [accountId, dispatch, followingList]);

  const loadMore = useDebouncedCallback(
    () => {
      if (accountId) {
        dispatch(expandFollowing(accountId));
      }
    },
    300,
    { leading: true },
  );

  const relationship = useRelationship(accountId);

  const followedId = relationship?.followed_by ? currentAccountId : null;
  const followingExceptMeHidden = !!(
    account?.hide_collections &&
    followingList?.items.length === 0 &&
    followedId
  );

  const footer = followingExceptMeHidden && (
    <div className='empty-column-indicator'>
      <FormattedMessage
        id='following.hide_other_following'
        defaultMessage='This user has chosen to not make the rest of who they follow visible'
        tagName='span'
      />
    </div>
  );

  const domain = account?.acct.split('@')[1];
  return (
    <AccountList
      accountId={accountId}
      append={domain && <RemoteHint domain={domain} url={account.url} />}
      emptyMessage={<EmptyMessage account={account} />}
      header={
        accountId && (
          <AccountListHeader
            accountId={accountId}
            titleText={titleText}
            total={account?.following_count}
          />
        )
      }
      footer={footer}
      list={followingList}
      loadMore={loadMore}
      prependAccountId={followedId}
      scrollKey='following'
    />
  );
};

const EmptyMessage: FC<EmptyMessageProps> = (props) => (
  <BaseEmptyMessage
    {...props}
    defaultMessage={
      <FormattedMessage
        id='account.follows.empty'
        defaultMessage="This user doesn't follow anyone yet."
      />
    }
  />
);

// eslint-disable-next-line import/no-default-export -- Used by async components.
export default Followers;
