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

import { FormattedMessage } from 'react-intl';

import classNames from 'classnames';
import { Link } from 'react-router-dom';

import AddIcon from '@/material-icons/400-24px/add.svg?react';
import { DisplayName } from 'mastodon/components/display_name';
import { EmptyState } from 'mastodon/components/empty_state';
import { Icon } from 'mastodon/components/icon';
import { LoadingIndicator } from 'mastodon/components/loading_indicator';
import { ItemList } from 'mastodon/components/scrollable_list/components';
import { useAccount } from 'mastodon/hooks/useAccount';
import { useAccountId, useCurrentAccountId } from 'mastodon/hooks/useAccountId';
import {
  fetchCollectionsCreatedByAccount,
  selectAccountCollections,
} from 'mastodon/reducers/slices/collections';
import { useAppSelector, useAppDispatch } from 'mastodon/store';

import { CollectionListItem } from '../components/collection_list_item';
import {
  messages as editorMessages,
  MaxCollectionsCallout,
  userCollectionLimit,
} from '../editor';
import classes from '../styles.module.scss';

export const NewCollectionButton: React.FC<{
  compact?: boolean;
  secondary?: boolean;
  onClick?: () => void;
  children?: ReactNode;
}> = ({ compact, secondary, onClick, children }) => (
  <Link
    to='/collections/new'
    className={classNames(
      'button',
      compact && 'button--compact',
      secondary && 'button-secondary',
    )}
    onClick={onClick}
  >
    <Icon id='plus' icon={AddIcon} />
    {children ?? <FormattedMessage {...editorMessages.newCollection} />}
  </Link>
);

export const CollectionListError: React.FC = () => (
  <EmptyState
    image={null}
    className={classes.error}
    message={
      <FormattedMessage
        id='collections.error_loading_collections'
        defaultMessage='There was an error when trying to load these collections.'
      />
    }
  />
);

export function useCollectionsCreatedBy(accountId: string | null | undefined) {
  const dispatch = useAppDispatch();

  useEffect(() => {
    if (accountId) {
      void dispatch(fetchCollectionsCreatedByAccount({ accountId }));
    }
  }, [dispatch, accountId]);

  return useAppSelector((state) =>
    selectAccountCollections(state, accountId, 'createdBy'),
  );
}

export const CollectionsCreatedByAccount: React.FC = () => {
  const me = useCurrentAccountId();
  const accountId = useAccountId();
  const account = useAccount(accountId);

  const { collections, status } = useCollectionsCreatedBy(accountId);

  const canCreateMoreCollections = collections.length < userCollectionLimit;
  const isOwnCollectionPage = accountId === me;
  const showCreateButton =
    isOwnCollectionPage && status === 'idle' && canCreateMoreCollections;

  if (status === 'error' || !accountId) {
    return <CollectionListError />;
  }

  if (status === 'loading') {
    return <LoadingIndicator />;
  }

  if (collections.length === 0) {
    if (isOwnCollectionPage) {
      return (
        <EmptyState
          title={
            <FormattedMessage
              id='empty_column.account_featured_self.showcase_accounts'
              defaultMessage='Showcase your favorite accounts'
            />
          }
          message={
            <FormattedMessage
              id='empty_column.account_featured_self.showcase_accounts_desc'
              defaultMessage='Collections are curated lists of accounts to help others discover more of the Fediverse.'
            />
          }
        >
          <NewCollectionButton compact />
        </EmptyState>
      );
    } else {
      return (
        <EmptyState
          title={
            <FormattedMessage
              id='empty_column.collections'
              defaultMessage='{acct} has not created any collections yet.'
              values={{
                acct: <DisplayName variant='simple' account={account} />,
              }}
            />
          }
        />
      );
    }
  }

  return (
    <>
      <div className={classes.listHeader}>
        <h2 className={classes.subHeading}>
          <FormattedMessage
            id='collections.list.collections_with_count'
            defaultMessage='{count, plural, one {# Collection} other {# Collections}}'
            values={{
              count: collections.length,
            }}
          />
        </h2>
        {showCreateButton && <NewCollectionButton compact />}
      </div>
      <ItemList>
        {isOwnCollectionPage && !canCreateMoreCollections && (
          <MaxCollectionsCallout className={classes.maxCollectionsError} />
        )}
        {collections.map((item, index) => (
          <CollectionListItem
            withTimestamp
            withAuthorHandle={false}
            key={item.id}
            collection={item}
            positionInList={index + 1}
            listSize={collections.length}
          />
        ))}
      </ItemList>
    </>
  );
};
