import './nav-menu.css';

import { t, Trans } from '@lingui/macro';
import { ControlledMenu, MenuDivider, MenuItem } from '@szhsin/react-menu';
import { memo } from 'preact/compat';
import { useEffect, useMemo, useRef, useState } from 'preact/hooks';
import { useLongPress } from 'use-long-press';
import { useSnapshot } from 'valtio';

import { api } from '../utils/api';
import { getLists } from '../utils/lists';
import safeBoundingBoxPadding from '../utils/safe-bounding-box-padding';
import states from '../utils/states';
import store from '../utils/store';
import { getCurrentAccountID } from '../utils/store-utils';
import supports from '../utils/supports';

import Avatar from './avatar';
import Icon from './icon';
import MenuLink from './menu-link';
import SubMenu2 from './submenu2';

function NavMenu(props) {
  const snapStates = useSnapshot(states);
  const { masto, instance, authenticated } = api();

  const [currentAccount, moreThanOneAccount] = useMemo(() => {
    const accounts = store.local.getJSON('accounts') || [];
    const acc =
      accounts.find((account) => account.info.id === getCurrentAccountID()) ||
      accounts[0];
    return [acc, accounts.length > 1];
  }, []);

  // Home = Following
  // But when in multi-column mode, Home becomes columns of anything
  // User may choose pin or not to pin Following
  // If user doesn't pin Following, we show it in the menu
  const showFollowing =
    (snapStates.settings.shortcutsViewMode === 'multi-column' ||
      (!snapStates.settings.shortcutsViewMode &&
        snapStates.settings.shortcutsColumnsMode)) &&
    !snapStates.shortcuts.find((pin) => pin.type === 'following');

  const bindLongPress = useLongPress(
    () => {
      states.showAccounts = true;
    },
    {
      threshold: 600,
      detect: 'touch',
      cancelOnMovement: true,
    },
  );

  const buttonRef = useRef();
  const [menuState, setMenuState] = useState(undefined);

  const boundingBoxPadding = safeBoundingBoxPadding([
    0,
    0,
    snapStates.settings.shortcutsViewMode === 'tab-menu-bar' ? 50 : 0,
    0,
  ]);

  const mutesIterator = useRef();
  async function fetchMutes(firstLoad) {
    if (firstLoad || !mutesIterator.current) {
      mutesIterator.current = masto.v1.mutes.list({
        limit: 80,
      });
    }
    const results = await mutesIterator.current.next();
    return results;
  }

  const blocksIterator = useRef();
  async function fetchBlocks(firstLoad) {
    if (firstLoad || !blocksIterator.current) {
      blocksIterator.current = masto.v1.blocks.list({
        limit: 80,
      });
    }
    const results = await blocksIterator.current.next();
    return results;
  }

  const supportsLists = supports('@mastodon/lists');
  const [lists, setLists] = useState([]);
  useEffect(() => {
    if (!supportsLists) return;
    if (menuState === 'open') {
      getLists().then(setLists);
    }
  }, [menuState === 'open']);

  const buttonClickTS = useRef();
  return (
    <>
      <button
        ref={buttonRef}
        type="button"
        class={`button plain nav-menu-button ${
          moreThanOneAccount ? 'with-avatar' : ''
        } ${menuState === 'open' ? 'active' : ''}`}
        style={{ position: 'relative' }}
        onClick={() => {
          buttonClickTS.current = Date.now();
          setMenuState((state) => (!state ? 'open' : undefined));
        }}
        onContextMenu={(e) => {
          e.preventDefault();
          states.showAccounts = true;
        }}
        {...bindLongPress()}
      >
        {moreThanOneAccount && (
          <Avatar
            url={
              currentAccount?.info?.avatar || currentAccount?.info?.avatarStatic
            }
            size="l"
            squircle={currentAccount?.info?.bot}
          />
        )}
        <Icon icon="menu" size={moreThanOneAccount ? 's' : 'l'} alt={t`Menu`} />
      </button>
      <ControlledMenu
        menuClassName="nav-menu"
        state={menuState}
        anchorRef={buttonRef}
        onClose={() => {
          setMenuState(undefined);
        }}
        containerProps={{
          style: {
            zIndex: 10,
          },
          onClick: () => {
            if (Date.now() - buttonClickTS.current < 300) {
              return;
            }
            // setMenuState(undefined);
          },
        }}
        portal={{
          target: document.body,
        }}
        {...props}
        overflow="auto"
        viewScroll="close"
        position="anchor"
        align="center"
        boundingBoxPadding={boundingBoxPadding}
        unmountOnClose
      >
        {!!snapStates.appVersion?.commitHash &&
          __COMMIT_HASH__ !== snapStates.appVersion.commitHash && (
            <div class="top-menu">
              <MenuItem
                onClick={() => {
                  const yes = confirm(t`Reload page now to update?`);
                  if (yes) {
                    (async () => {
                      try {
                        location.reload();
                      } catch (e) {}
                    })();
                  }
                }}
              >
                <Icon icon="sparkles" class="sparkle-icon" size="l" />{' '}
                <span>
                  <Trans>New update available…</Trans>
                </span>
              </MenuItem>
              <MenuDivider />
            </div>
          )}
        <section>
          <MenuLink to="/">
            <Icon icon="home" size="l" />{' '}
            <span>
              <Trans>Home</Trans>
            </span>
          </MenuLink>
          {authenticated ? (
            <>
              {showFollowing && (
                <MenuLink to="/following">
                  <Icon icon="following" size="l" />{' '}
                  <span>
                    <Trans>Following</Trans>
                  </span>
                </MenuLink>
              )}
              <MenuLink to="/catchup">
                <Icon icon="history2" size="l" />
                <span>
                  <Trans>Catch-up</Trans>
                </span>
              </MenuLink>
              {supports('@mastodon/mentions') && (
                <MenuLink to="/mentions">
                  <Icon icon="at" size="l" />{' '}
                  <span>
                    <Trans>Mentions</Trans>
                  </span>
                </MenuLink>
              )}
              <MenuLink to="/notifications">
                <Icon icon="notification" size="l" />{' '}
                <span>
                  <Trans>Notifications</Trans>
                </span>
                {snapStates.notificationsShowNew && (
                  <sup title={t`New`} style={{ opacity: 0.5 }}>
                    {' '}
                    &bull;
                  </sup>
                )}
              </MenuLink>
              <MenuDivider />
              {currentAccount?.info?.id && (
                <MenuLink to={`/${instance}/a/${currentAccount.info.id}`}>
                  <Icon icon="user" size="l" />{' '}
                  <span>
                    <Trans>Profile</Trans>
                  </span>
                </MenuLink>
              )}
              {lists?.length > 0 ? (
                <SubMenu2
                  menuClassName="nav-submenu"
                  overflow="auto"
                  gap={-8}
                  label={
                    <>
                      <Icon icon="list" size="l" />
                      <span class="menu-grow">
                        <Trans>Lists</Trans>
                      </span>
                      <Icon icon="chevron-right" />
                    </>
                  }
                >
                  <MenuLink to="/l">
                    <span>
                      <Trans>All Lists</Trans>
                    </span>
                  </MenuLink>
                  {lists?.length > 0 && (
                    <>
                      <MenuDivider />
                      {lists.map((list) => (
                        <MenuLink key={list.id} to={`/l/${list.id}`}>
                          <span>{list.title}</span>
                        </MenuLink>
                      ))}
                    </>
                  )}
                </SubMenu2>
              ) : (
                supportsLists && (
                  <MenuLink to="/l">
                    <Icon icon="list" size="l" />
                    <span>
                      <Trans>Lists</Trans>
                    </span>
                  </MenuLink>
                )
              )}
              <MenuLink to="/b">
                <Icon icon="bookmark" size="l" />{' '}
                <span>
                  <Trans>Bookmarks</Trans>
                </span>
              </MenuLink>
              <SubMenu2
                menuClassName="nav-submenu"
                overflow="auto"
                gap={-8}
                label={
                  <>
                    <Icon icon="more" size="l" />
                    <span class="menu-grow">
                      <Trans>More…</Trans>
                    </span>
                    <Icon icon="chevron-right" />
                  </>
                }
              >
                <MenuLink to="/f">
                  <Icon icon="heart" size="l" />{' '}
                  <span>
                    <Trans>Likes</Trans>
                  </span>
                </MenuLink>
                <MenuLink to="/fh">
                  <Icon icon="hashtag" size="l" />{' '}
                  <span>
                    <Trans>Followed Hashtags</Trans>
                  </span>
                </MenuLink>
                <MenuDivider />
                {supports('@mastodon/filters') && (
                  <MenuLink to="/ft">
                    <Icon icon="filters" size="l" />{' '}
                    <span>
                      <Trans>Filters</Trans>
                    </span>
                  </MenuLink>
                )}
                <MenuItem
                  onClick={() => {
                    states.showGenericAccounts = {
                      id: 'mute',
                      heading: t`Muted users`,
                      fetchAccounts: fetchMutes,
                      excludeRelationshipAttrs: ['muting'],
                    };
                  }}
                >
                  <Icon icon="mute" size="l" />{' '}
                  <span>
                    <Trans>Muted users…</Trans>
                  </span>
                </MenuItem>
                <MenuItem
                  onClick={() => {
                    states.showGenericAccounts = {
                      id: 'block',
                      heading: t`Blocked users`,
                      fetchAccounts: fetchBlocks,
                      excludeRelationshipAttrs: ['blocking'],
                    };
                  }}
                >
                  <Icon icon="block" size="l" />{' '}
                  <span>
                    <Trans>Blocked users…</Trans>
                  </span>
                </MenuItem>{' '}
              </SubMenu2>
              <MenuDivider />
              <MenuItem
                onClick={() => {
                  states.showAccounts = true;
                }}
              >
                <Icon icon="group" size="l" />{' '}
                <span>
                  <Trans>Accounts…</Trans>
                </span>
              </MenuItem>
            </>
          ) : (
            <>
              <MenuDivider />
              <MenuLink to="/login">
                <Icon icon="user" size="l" />{' '}
                <span>
                  <Trans>Log in</Trans>
                </span>
              </MenuLink>
            </>
          )}
        </section>
        <section>
          <MenuDivider />
          <MenuLink to={`/search`}>
            <Icon icon="search" size="l" />{' '}
            <span>
              <Trans>Search</Trans>
            </span>
          </MenuLink>
          <MenuLink to={`/${instance}/trending`}>
            <Icon icon="chart" size="l" />{' '}
            <span>
              <Trans>Trending</Trans>
            </span>
          </MenuLink>
          <MenuLink to={`/${instance}/p/l`}>
            <Icon icon="building" size="l" />{' '}
            <span>
              <Trans>Local</Trans>
            </span>
          </MenuLink>
          <MenuLink to={`/${instance}/p`}>
            <Icon icon="earth" size="l" />{' '}
            <span>
              <Trans>Federated</Trans>
            </span>
          </MenuLink>
          {authenticated ? (
            <>
              <MenuDivider className="divider-grow" />
              <MenuItem
                onClick={() => {
                  states.showKeyboardShortcutsHelp = true;
                }}
              >
                <Icon icon="keyboard" size="l" />{' '}
                <span>
                  <Trans>Keyboard shortcuts</Trans>
                </span>
              </MenuItem>
              <MenuItem
                onClick={() => {
                  states.showShortcutsSettings = true;
                }}
              >
                <Icon icon="shortcut" size="l" />{' '}
                <span>
                  <Trans>Shortcuts / Columns…</Trans>
                </span>
              </MenuItem>
              <MenuItem
                onClick={() => {
                  states.showSettings = true;
                }}
              >
                <Icon icon="gear" size="l" />{' '}
                <span>
                  <Trans>Settings…</Trans>
                </span>
              </MenuItem>
            </>
          ) : (
            <>
              <MenuDivider />
              <MenuItem
                onClick={() => {
                  states.showSettings = true;
                }}
              >
                <Icon icon="gear" size="l" />{' '}
                <span>
                  <Trans>Settings…</Trans>
                </span>
              </MenuItem>
            </>
          )}
        </section>
      </ControlledMenu>
    </>
  );
}

export default memo(NavMenu);
