// @flow
import * as ICONS from 'constants/icons';
import { SETTINGS } from 'lbry-redux';
import * as PAGES from 'constants/pages';
import React from 'react';
import { withRouter } from 'react-router';
import classnames from 'classnames';
import Button from 'component/button';
import WunderBar from 'component/wunderbar';
import Icon from 'component/common/icon';
import { Menu, MenuList, MenuButton, MenuItem } from '@reach/menu-button';
import NavigationButton from 'component/navigationButton';
import { LOGO_TITLE } from 'config';
import { useIsMobile } from 'effects/use-screensize';
import NotificationBubble from 'component/notificationBubble';
import NotificationHeaderButton from 'component/notificationHeaderButton';
import ChannelThumbnail from 'component/channelThumbnail';
// @if TARGET='app'
import { remote } from 'electron';
import { IS_MAC } from 'component/app/view';
// @endif

type Props = {
  user: ?User,
  balance: string,
  balance: number,
  roundedBalance: string,
  roundedSpendableBalance: string,
  history: {
    entities: {}[],
    goBack: () => void,
    goForward: () => void,
    index: number,
    length: number,
    location: { pathname: string },
    push: string => void,
    replace: string => void,
  },
  currentTheme: string,
  automaticDarkModeEnabled: boolean,
  setClientSetting: (string, boolean | string, ?boolean) => void,
  hideBalance: boolean,
  email: ?string,
  authenticated: boolean,
  authHeader: boolean,
  backout: {
    backLabel?: string,
    backNavDefault?: string,
    title: string,
    simpleTitle: string, // Just use the same value as `title` if `title` is already short (~< 10 chars), unless you have a better idea for title overlfow on mobile
  },
  syncError: ?string,
  emailToVerify?: string,
  signOut: () => void,
  openChannelCreate: () => void,
  openSignOutModal: () => void,
  clearEmailEntry: () => void,
  clearPasswordEntry: () => void,
  hasNavigated: boolean,
  sidebarOpen: boolean,
  setSidebarOpen: boolean => void,
  isAbsoluteSideNavHidden: boolean,
  hideCancel: boolean,
  activeChannelClaim: ?ChannelClaim,
};

const Header = (props: Props) => {
  const {
    balance,
    roundedBalance,
    roundedSpendableBalance,
    history,
    setClientSetting,
    currentTheme,
    automaticDarkModeEnabled,
    hideBalance,
    email,
    authenticated,
    authHeader,
    signOut,
    syncError,
    openSignOutModal,
    clearEmailEntry,
    clearPasswordEntry,
    emailToVerify,
    backout,
    sidebarOpen,
    setSidebarOpen,
    isAbsoluteSideNavHidden,
    user,
    hideCancel,
    activeChannelClaim,
  } = props;
  const isMobile = useIsMobile();
  // on the verify page don't let anyone escape other than by closing the tab to keep session data consistent
  const isVerifyPage = history.location.pathname.includes(PAGES.AUTH_VERIFY);
  const isSignUpPage = history.location.pathname.includes(PAGES.AUTH);
  const isSignInPage = history.location.pathname.includes(PAGES.AUTH_SIGNIN);
  const isPwdResetPage = history.location.pathname.includes(PAGES.AUTH_PASSWORD_RESET);
  const hasBackout = Boolean(backout);
  const { backLabel, backNavDefault, title: backTitle, simpleTitle: simpleBackTitle } = backout || {};
  const notificationsEnabled = (user && user.experimental_ui) || false;
  const activeChannelUrl = activeChannelClaim && activeChannelClaim.permanent_url;

  // Sign out if they click the "x" when they are on the password prompt
  const authHeaderAction = syncError ? { onClick: signOut } : { navigate: '/' };
  const homeButtonNavigationProps = isVerifyPage ? {} : authHeader ? authHeaderAction : { navigate: '/' };
  const closeButtonNavigationProps = {
    onClick: () => {
      clearEmailEntry();
      clearPasswordEntry();

      if (syncError) {
        signOut();
      }

      if (isSignInPage && !emailToVerify) {
        history.goBack();
      } else if (isSignUpPage) {
        history.goBack();
      } else if (isPwdResetPage) {
        history.goBack();
      } else {
        history.push('/');
      }
    },
  };

  function onBackout(e) {
    const { history, hasNavigated } = props;
    const { goBack, replace } = history;

    window.removeEventListener('popstate', onBackout);

    if (e.type !== 'popstate') {
      // if not initiated by pop (back button)
      if (hasNavigated && !backNavDefault) {
        goBack();
      } else {
        replace(backNavDefault || `/`);
      }
    }
  }

  React.useEffect(() => {
    if (hasBackout) {
      window.addEventListener('popstate', onBackout);
      return () => window.removeEventListener('popstate', onBackout);
    }
  }, [hasBackout]);

  function handleThemeToggle() {
    if (automaticDarkModeEnabled) {
      setClientSetting(SETTINGS.AUTOMATIC_DARK_MODE_ENABLED, false);
    }

    if (currentTheme === 'dark') {
      setClientSetting(SETTINGS.THEME, 'light', true);
    } else {
      setClientSetting(SETTINGS.THEME, 'dark', true);
    }
  }

  const loginButtons = (
    <div className="header__auth-buttons">
      <Button navigate={`/$/${PAGES.AUTH_SIGNIN}`} button="link" label={__('Log In')} className="mobile-hidden" />
      <Button navigate={`/$/${PAGES.AUTH}`} button="primary" label={__('Sign Up')} />
    </div>
  );

  type BalanceButtonProps = { className: string };
  const BalanceButton = (balanceButtonProps: BalanceButtonProps) => (
    <Button
      title={
        balance > 0
          ? __('Immediately spendable: %spendable_balance%', { spendable_balance: roundedSpendableBalance })
          : __('Your Wallet')
      }
      navigate={`/$/${PAGES.WALLET}`}
      className={balanceButtonProps.className}
      label={hideBalance || Number(roundedBalance) === 0 ? __('Your Wallet') : roundedBalance}
      icon={ICONS.LBC}
      // @if TARGET='app'
      onDoubleClick={e => {
        e.stopPropagation();
      }}
      // @endif
    />
  );

  return (
    <header
      className={classnames('header', {
        'header--minimal': authHeader,
        // @if TARGET='app'
        'header--mac': IS_MAC,
        // @endif
      })}
      // @if TARGET='app'
      onDoubleClick={e => {
        remote.getCurrentWindow().maximize();
      }}
      // @endif
    >
      <div className="header__contents">
        {!authHeader && backout ? (
          <div className="card__actions--between">
            <Button
              onClick={onBackout}
              button="link"
              label={(backLabel && backLabel) || __('Cancel')}
              icon={ICONS.ARROW_LEFT}
            />
            {backTitle && <h1 className="header__auth-title">{isMobile ? simpleBackTitle || backTitle : backTitle}</h1>}
            {authenticated || !IS_WEB ? (
              <BalanceButton className="header__navigation-item menu__title header__navigation-item--balance" />
            ) : (
              loginButtons
            )}
          </div>
        ) : (
          <>
            <div className="header__navigation">
              {!authHeader && (
                <span style={{ position: 'relative' }}>
                  <Button
                    aria-label={
                      sidebarOpen
                        ? __('Close sidebar - hide channels you are following.')
                        : __('Expand sidebar - view channels you are following.')
                    }
                    className="header__navigation-item menu__title header__navigation-item--icon"
                    icon={ICONS.MENU}
                    onClick={() => setSidebarOpen(!sidebarOpen)}
                  >
                    {isAbsoluteSideNavHidden && isMobile && notificationsEnabled && <NotificationBubble />}
                  </Button>
                </span>
              )}
              <Button
                className="header__navigation-item header__navigation-item--lbry"
                // @if TARGET='app'
                label={'LBRY'}
                // @endif
                // @if TARGET='web'
                label={LOGO_TITLE} // eslint-disable-line
                // @endif
                icon={ICONS.LBRY}
                onClick={() => {
                  if (history.location.pathname === '/') window.location.reload();
                }}
                // @if TARGET='app'
                onDoubleClick={e => {
                  e.stopPropagation();
                }}
                // @endif
                {...homeButtonNavigationProps}
              />

              {!authHeader && (
                <div className="header__center">
                  {/* @if TARGET='app' */}
                  {!authHeader && (
                    <div className="header__buttons">
                      <NavigationButton isBackward history={history} />
                      <NavigationButton isBackward={false} history={history} />
                    </div>
                  )}
                  {/* @endif */}

                  {!authHeader && <WunderBar />}

                  <HeaderMenuButtons
                    authenticated={authenticated}
                    notificationsEnabled={notificationsEnabled}
                    history={history}
                    handleThemeToggle={handleThemeToggle}
                    currentTheme={currentTheme}
                    activeChannelUrl={activeChannelUrl}
                    openSignOutModal={openSignOutModal}
                    email={email}
                    signOut={signOut}
                  />
                </div>
              )}
            </div>

            {!authHeader && !backout ? (
              <div className={classnames('header__menu', { 'header__menu--with-balance': !IS_WEB || authenticated })}>
                {(!IS_WEB || authenticated) && (
                  <BalanceButton className="header__navigation-item menu__title header__navigation-item--balance mobile-hidden" />
                )}

                {IS_WEB && !authenticated && loginButtons}
              </div>
            ) : (
              !isVerifyPage &&
              !hideCancel && (
                <div className="header__menu">
                  {/* Add an empty span here so we can use the same style as above */}
                  {/* This pushes the close button to the right side */}
                  <span />

                  <Button
                    title={__('Go Back')}
                    button="alt"
                    // className="button--header-close"
                    icon={ICONS.REMOVE}
                    {...closeButtonNavigationProps}
                    // @if TARGET='app'
                    onDoubleClick={e => {
                      e.stopPropagation();
                    }}
                    // @endif
                  />
                </div>
              )
            )}
          </>
        )}
      </div>
    </header>
  );
};

type HeaderMenuButtonProps = {
  authenticated: boolean,
  notificationsEnabled: boolean,
  history: { push: string => void },
  handleThemeToggle: string => void,
  currentTheme: string,
  activeChannelUrl: ?string,
  openSignOutModal: () => void,
  email: ?string,
  signOut: () => void,
};

function HeaderMenuButtons(props: HeaderMenuButtonProps) {
  const {
    authenticated,
    notificationsEnabled,
    history,
    handleThemeToggle,
    currentTheme,
    activeChannelUrl,
    openSignOutModal,
    email,
    signOut,
  } = props;

  return (
    <div className="header__buttons">
      {(authenticated || !IS_WEB) && (
        <Menu>
          <MenuButton
            aria-label={__('Publish a file, or create a channel')}
            title={__('Publish a file, or create a channel')}
            className="header__navigation-item menu__title header__navigation-item--icon mobile-hidden"
            // @if TARGET='app'
            onDoubleClick={e => {
              e.stopPropagation();
            }}
            // @endif
          >
            <Icon size={18} icon={ICONS.PUBLISH} aria-hidden />
          </MenuButton>

          <MenuList className="menu__list--header">
            <MenuItem className="menu__link" onSelect={() => history.push(`/$/${PAGES.UPLOAD}`)}>
              <Icon aria-hidden icon={ICONS.PUBLISH} />
              {__('Upload')}
            </MenuItem>
            <MenuItem className="menu__link" onSelect={() => history.push(`/$/${PAGES.CHANNEL_NEW}`)}>
              <Icon aria-hidden icon={ICONS.CHANNEL} />
              {__('New Channel')}
            </MenuItem>
          </MenuList>
        </Menu>
      )}

      {notificationsEnabled && <NotificationHeaderButton />}

      <Menu>
        <MenuButton
          aria-label={__('Settings')}
          title={__('Settings')}
          className="header__navigation-item menu__title header__navigation-item--icon  mobile-hidden"
          // @if TARGET='app'
          onDoubleClick={e => {
            e.stopPropagation();
          }}
          // @endif
        >
          <Icon size={18} icon={ICONS.SETTINGS} aria-hidden />
        </MenuButton>
        <MenuList className="menu__list--header">
          <MenuItem className="menu__link" onSelect={() => history.push(`/$/${PAGES.SETTINGS}`)}>
            <Icon aria-hidden tootlip icon={ICONS.SETTINGS} />
            {__('Settings')}
          </MenuItem>
          <MenuItem className="menu__link" onSelect={() => history.push(`/$/${PAGES.HELP}`)}>
            <Icon aria-hidden icon={ICONS.HELP} />
            {__('Help')}
          </MenuItem>
          <MenuItem className="menu__link" onSelect={handleThemeToggle}>
            <Icon icon={currentTheme === 'light' ? ICONS.DARK : ICONS.LIGHT} />
            {currentTheme === 'light' ? __('Dark') : __('Light')}
          </MenuItem>
        </MenuList>
      </Menu>

      {(authenticated || !IS_WEB) && (
        <Menu>
          <MenuButton
            aria-label={__('Your account')}
            title={__('Your account')}
            className={classnames('header__navigation-item mobile-hidden', {
              'menu__title header__navigation-item--icon': !activeChannelUrl,
              'header__navigation-item--profile-pic': activeChannelUrl,
            })}
            // @if TARGET='app'
            onDoubleClick={e => {
              e.stopPropagation();
            }}
            // @endif
          >
            {activeChannelUrl ? (
              <ChannelThumbnail uri={activeChannelUrl} />
            ) : (
              <Icon size={18} icon={ICONS.ACCOUNT} aria-hidden />
            )}
          </MenuButton>
          <MenuList className="menu__list--header">
            <MenuItem className="menu__link" onSelect={() => history.push(`/$/${PAGES.UPLOADS}`)}>
              <Icon aria-hidden icon={ICONS.PUBLISH} />
              {__('Uploads')}
            </MenuItem>
            <MenuItem className="menu__link" onSelect={() => history.push(`/$/${PAGES.CHANNELS}`)}>
              <Icon aria-hidden icon={ICONS.CHANNEL} />
              {__('Channels')}
            </MenuItem>
            <MenuItem className="menu__link" onSelect={() => history.push(`/$/${PAGES.CREATOR_DASHBOARD}`)}>
              <Icon aria-hidden icon={ICONS.ANALYTICS} />
              {__('Creator Analytics')}
            </MenuItem>
            <MenuItem className="menu__link" onSelect={() => history.push(`/$/${PAGES.REWARDS}`)}>
              <Icon aria-hidden icon={ICONS.REWARDS} />
              {__('Rewards')}
            </MenuItem>
            <MenuItem className="menu__link" onSelect={() => history.push(`/$/${PAGES.INVITE}`)}>
              <Icon aria-hidden icon={ICONS.INVITE} />
              {__('Invites')}
            </MenuItem>

            {authenticated ? (
              <MenuItem onSelect={IS_WEB ? signOut : openSignOutModal}>
                <div className="menu__link">
                  <Icon aria-hidden icon={ICONS.SIGN_OUT} />
                  {__('Sign Out')}
                </div>
                <span className="menu__link-help">{email}</span>
              </MenuItem>
            ) : !IS_WEB ? (
              <>
                <MenuItem className="menu__link" onSelect={() => history.push(`/$/${PAGES.AUTH}`)}>
                  <Icon aria-hidden icon={ICONS.SIGN_UP} />
                  {__('Sign Up')}
                </MenuItem>
                <MenuItem className="menu__link" onSelect={() => history.push(`/$/${PAGES.AUTH_SIGNIN}`)}>
                  <Icon aria-hidden icon={ICONS.SIGN_IN} />
                  {__('Sign In')}
                </MenuItem>
              </>
            ) : null}
          </MenuList>
        </Menu>
      )}
    </div>
  );
}

export default withRouter(Header);