import { useState, useEffect } from 'react';
import { Link, useLocation } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import Plebbit from '@plebbit/plebbit-js/dist/browser/index.js';
import { Subplebbit, useSubplebbit, useSubplebbitStats } from '@plebbit/plebbit-react-hooks';
import { useDefaultSubplebbitsState } from '../../../hooks/use-default-subplebbits';
import { useDefaultSubplebbitTags } from '../../../hooks/use-default-subplebbits-tags';
import useIsMobile from '../../../hooks/use-is-mobile';
import useIsSubplebbitOffline from '../../../hooks/use-is-subplebbit-offline';
import LoadingEllipsis from '../../../components/loading-ellipsis';
import Tooltip from '../../../components/tooltip';
import styles from '../home.module.css';
import { nsfwTags } from '../home';

const Board = ({ subplebbit, isMobile }: { subplebbit: Subplebbit; isMobile: boolean }) => {
  const { t } = useTranslation();
  const { address, tags } = subplebbit || {};
  const nsfwTag = tags?.find((tag: string) => nsfwTags.includes(tag));

  let stats = useSubplebbitStats({ subplebbitAddress: address });

  const subplebbitData = useSubplebbit({ subplebbitAddress: address });
  const { isOffline, isOnlineStatusLoading, offlineIconClass, offlineTitle } = useIsSubplebbitOffline(subplebbitData);

  const displayAddress = address && Plebbit.getShortAddress(address);
  const showOfflineIcon = address && (isOffline || isOnlineStatusLoading);

  const title =
    subplebbitData?.title ||
    (subplebbitData?.updatedAt ? (displayAddress.endsWith('.eth') || displayAddress.endsWith('.sol') ? displayAddress.slice(0, -4) : displayAddress) : '?');

  return (
    <tr className={styles.subplebbit} key={address}>
      <td className={styles.boardAddress}>
        <p className={styles.boardCell}>
          <Link to={`/p/${address}`}>{displayAddress}</Link>
          {nsfwTag && <span className={styles.nsfw}> ({t(nsfwTag)})</span>}
          {showOfflineIcon && (
            <span className={styles.offlineIconContainer}>
              <Tooltip content={offlineTitle}>
                <span className={`${styles.offlineIcon} ${offlineIconClass}`} />
              </Tooltip>
            </span>
          )}
        </p>
      </td>
      <td className={styles.boardTitle}>
        <p className={styles.boardCell}>{title}</p>
      </td>
      {!isMobile && (
        <>
          <td className={styles.boardPPH}>
            <p className={styles.boardCell}>{stats.hourPostCount ?? '?'}</p>
          </td>
          <td className={styles.boardTags}>
            <p className={styles.boardCell}>
              {tags.map((tag: string, index: number) => (
                <span key={tag}>
                  <Link to={`/${tag}`}>{tag}</Link>
                  {index < tags.length - 1 && ', '}
                </span>
              ))}
            </p>
          </td>
        </>
      )}
    </tr>
  );
};

const BoardsList = ({ multisub }: { multisub: Subplebbit[] }) => {
  const { t } = useTranslation();
  const location = useLocation();
  const [displayCount, setDisplayCount] = useState(15);
  const isMobile = useIsMobile();
  const { loading, error } = useDefaultSubplebbitsState();

  const currentTag = location.pathname.split('/').filter(Boolean)[0];
  const tags = useDefaultSubplebbitTags(multisub);

  useEffect(() => {
    setDisplayCount(15);
  }, [currentTag]);

  if (loading) {
    return (
      <div className={styles.boardsBox}>
        <span className={styles.loading}>
          <LoadingEllipsis string={t('loading_default_boards')} />
        </span>
      </div>
    );
  }

  if (error) {
    return (
      <div className={styles.boardsBox}>
        <div className='red'>{error.message}</div>
      </div>
    );
  }

  const filteredBoards = (currentTag && tags.includes(currentTag) ? multisub.filter((sub) => sub?.tags?.includes(currentTag)) : multisub).slice(0, displayCount);

  const totalBoardCount = currentTag && tags.includes(currentTag) ? multisub.filter((sub) => sub?.tags?.includes(currentTag)).length : multisub.length;

  const hasMoreBoards =
    currentTag && tags.includes(currentTag) ? displayCount < multisub.filter((sub) => sub?.tags?.includes(currentTag)).length : displayCount < multisub.length;

  return (
    <div className={styles.boardsBox}>
      <table className={styles.boardsList}>
        <colgroup>
          <col className={styles.boardAddress} />
          <col className={styles.boardTitle} />
        </colgroup>
        <thead>
          <tr>
            <th>{t('board')}</th>
            <th>{t('title')}</th>
            {!isMobile && (
              <th className={styles.boardPPH} title={t('pph')}>
                PPH
              </th>
            )}
            {!isMobile && <th>{t('tags')}</th>}
          </tr>
        </thead>
        <tbody>
          {filteredBoards.map((sub) => (
            <Board key={sub.address} subplebbit={sub} isMobile={isMobile} />
          ))}
        </tbody>
      </table>
      <div className={styles.displayCount}>
        {currentTag && tags.includes(currentTag)
          ? t('displaying_boards_with_tag', {
              filteredBoardsCount: filteredBoards.length,
              totalBoardCount: totalBoardCount,
              currentTag: `"${currentTag}"`,
              interpolation: { escapeValue: false },
            })
          : t('displaying_boards', { filteredBoardsCount: filteredBoards.length, totalBoardCount: totalBoardCount, interpolation: { escapeValue: false } })}
      </div>
      {hasMoreBoards && (
        <div className={styles.loadMoreButton}>
          [<span onClick={() => setDisplayCount((prevCount) => prevCount + 15)}>{t('load_more')}</span>]
        </div>
      )}
    </div>
  );
};

export default BoardsList;
