/* eslint-disable prefer-destructuring */
import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import throttle from 'lodash/throttle';
import MastheadLogo from './masthead-logo';
import MastheadSecondaryLinks from './masthead-secondary-links';
import MastheadSecondaryNavigation from './masthead-secondary-navigation';
import AccountLogin from './account-login';
import getAccountData from './account-data';
import MenuDisclosure from '../menu-disclosure/menu-disclosure';
import AccountNavigation from './account-navigation';
import CallToAction from '../call-to-action/call-to-action';
import { breakpointXLarge, urls } from '../../constants';
import 'reset-css/reset.css';
import '../color/color';
import '../grid/grid';
import '../interactions/interactions';
import '../media-queries/media-queries';
import '../rule/rule';
import '../typography/typography';
import css from './masthead.css';

const subscribe = urls.subscribe;
const initialWindowWidth = () => {
  if (typeof window !== 'undefined') {
    return window.innerWidth;
  }
  return undefined;
};

// Used React.memo() to address issue flagged by linter, so toggle function is only created once
/* eslint-disable react/jsx-no-bind */
const MastheadSecondary = React.memo(
  ({
    isLoggedIn,
    loginUrl,
    logoutUrl,
    mastheadLinks,
    selectedLink,
    showAccountNav,
    showLogin,
    showSubscribe,
    showGiftGivingButton,
    subscribeCtaText,
    subscribeUrl,
    username,
    manageMyAccountUrl,
    savedStoriesUrl,
    gsClientAdminUrl,
    mySubscriptionUrl,
    personalInfoUrl,
    billingUrl,
    newslettersAndPreferencesUrl,
    giftSubscriptionsUrl,
    helpUrl,
    isClientAdmin,
    isGroupSubscriber,
    fullName,
  }) => {
    const [windowWidth, setWindowWidth] = useState(initialWindowWidth());
    const [menuIsOpen, setMenuIsOpen] = useState(false);
    const [accountIsOpen, setAccountIsOpen] = useState(false);
    const inverse = menuIsOpen;
    const processedAccountDataMenu = getAccountData(
      loginUrl,
      logoutUrl,
      manageMyAccountUrl,
      savedStoriesUrl,
      gsClientAdminUrl,
      mySubscriptionUrl,
      personalInfoUrl,
      billingUrl,
      newslettersAndPreferencesUrl,
      giftSubscriptionsUrl,
      helpUrl,
    );
    if (showSubscribe) {
      processedAccountDataMenu['account-logged-in'] = processedAccountDataMenu[
        'account-logged-in'
      ].filter(link => link.name !== 'Billing');
    }
    if (isGroupSubscriber || isClientAdmin) {
      processedAccountDataMenu['account-logged-in'] = processedAccountDataMenu[
        'account-logged-in'
      ].filter(
        link => link.name !== 'Gift subscriptions' && link.name !== 'Billing',
      );
    }
    if (!isClientAdmin) {
      processedAccountDataMenu['account-logged-in'] = processedAccountDataMenu[
        'account-logged-in'
      ].filter(link => link.name !== 'Admin account');
      processedAccountDataMenu[
        'account-logged-in-main'
      ] = processedAccountDataMenu['account-logged-in-main'].filter(
        link => link.name !== 'Admin account',
      );
    }
    const processedAccountData = showLogin ? processedAccountDataMenu : null;
    const hasMastheadLinks = mastheadLinks && mastheadLinks.length;

    const toggle = e => {
      e.preventDefault();
      setAccountIsOpen(false);
      setMenuIsOpen(!menuIsOpen);
    };
    const toggleAccount = e => {
      e.preventDefault();
      setMenuIsOpen(false);
      setAccountIsOpen(!accountIsOpen);
    };

    // The window width is calculated as the dropdown menus exhibit changes in behaviour at
    // different breakpoints.
    useEffect(() => {
      const milliseconds = 200;
      const handleResize = throttle(() => {
        // On a number of mobile browsers the resize event handler fires on
        // scrolling due to the browser toolbar disappearing. To prevent unwanted
        // behaviour we check the width, ignoring any height changes.
        const newWindowWidth = window.innerWidth;
        if (newWindowWidth !== windowWidth) {
          setWindowWidth(newWindowWidth);
          if (newWindowWidth < breakpointXLarge) {
            setAccountIsOpen(false);
          }
          if (newWindowWidth >= breakpointXLarge) {
            setMenuIsOpen(false);
          }
        }
      }, milliseconds);

      window.addEventListener('resize', handleResize);
      return () => {
        window.removeEventListener('resize', handleResize);
      };
    });

    return (
      <header
        className={classnames(
          `${css['ds-masthead']} ${css['ds-masthead--secondary']}`,
          {
            [css['is-open']]: menuIsOpen,
            [css['account-is-open']]: accountIsOpen,
          },
        )}
      >
        <div className={css['ds-layout-masthead']}>
          <MastheadLogo />
          <div className={css['ds-masthead-nav']}>
            {hasMastheadLinks && (
              <nav className={css['ds-masthead-nav-alpha']}>
                <ul>
                  <MastheadSecondaryLinks
                    links={mastheadLinks}
                    selectedLink={selectedLink}
                    inverse={inverse}
                  />

                  <li
                    className={`${css['ds-masthead-nav-alpha__item']} ${
                      css['ds-masthead-nav-alpha__item--menu']
                    }`}
                  >
                    <MenuDisclosure
                      url='#sections'
                      menuIsOpen={menuIsOpen}
                      inverse={inverse}
                      onClick={toggle}
                      hideMenuText={showSubscribe}
                    />
                  </li>
                </ul>
              </nav>
            )}
            <div className={css['ds-masthead-nav-beta']}>
              {showSubscribe && (
                <div
                  className={`${css['ds-masthead-nav-beta__item']} ${
                    css['ds-masthead-nav-beta__item--call-to-action']
                  }`}
                >
                  <CallToAction
                    text={subscribeCtaText}
                    href={subscribeUrl}
                    inverse={inverse}
                  />
                </div>
              )}
              {!showSubscribe && showGiftGivingButton && (
                <div
                  className={`${css['ds-masthead-nav-beta__item']} ${
                    css['ds-masthead-nav-beta__item--call-to-action']
                  }`}
                >
                  <CallToAction
                    text='Give a gift'
                    href='https://subscribenow.economist.com/gift'
                    inverse={inverse}
                    data-analytics='masthead-gift-cta'
                  />
                </div>
              )}
              {showLogin && (
                <div
                  className={`${css['ds-masthead-nav-beta__item']} ${
                    css['ds-masthead-nav-beta__item--log-in']
                  }`}
                >
                  <AccountLogin
                    isLoggedIn={isLoggedIn}
                    loginUrl={loginUrl}
                    logoutUrl={showAccountNav ? null : logoutUrl}
                    inverse={inverse}
                    toggleAccount={toggleAccount}
                    expanded={accountIsOpen}
                    fullName={fullName}
                  />
                </div>
              )}
            </div>
          </div>
          {menuIsOpen && (
            <MastheadSecondaryNavigation
              accountData={processedAccountData}
              links={mastheadLinks}
              logoutUrl={logoutUrl}
              menuIsOpen={menuIsOpen}
              showAccountNav={false}
              showSubscribe={showSubscribe}
              showLogin={false}
              showNavToggle
              subscribeUrl={subscribeUrl}
              username={username}
              isLoggedIn={isLoggedIn}
            />
          )}
          {showLogin && (
            <AccountNavigation accountData={processedAccountData} />
          )}
        </div>
      </header>
    );
  },
);

MastheadSecondary.displayName = 'MastheadSecondary';

MastheadSecondary.defaultProps = {
  isLoggedIn: false,
  loginUrl: '',
  logoutUrl: '',
  mastheadLinks: null,
  selectedLink: null,
  showAccountNav: true,
  showLogin: false,
  showSubscribe: false,
  showGiftGivingButton: false,
  subscribeCtaText: 'Subscribe',
  subscribeUrl: subscribe,
  username: '',
  manageMyAccountUrl: '',
  savedStoriesUrl: '',
  gsClientAdminUrl: '',
  mySubscriptionUrl: '',
  personalInfoUrl: '',
  billingUrl: '',
  newslettersAndPreferencesUrl: '',
  giftSubscriptionsUrl: '',
  helpUrl: '',
  isClientAdmin: false,
  isGroupSubscriber: false,
  fullName: '',
};

MastheadSecondary.propTypes = {
  isLoggedIn: PropTypes.bool,
  loginUrl: PropTypes.string,
  logoutUrl: PropTypes.string,
  mastheadLinks: PropTypes.arrayOf(
    PropTypes.shape({
      text: PropTypes.string,
      href: PropTypes.string,
      id: PropTypes.string,
    }),
  ),
  /** The index position of the selected masthead link item. */
  selectedLink: PropTypes.number,
  showAccountNav: PropTypes.bool,
  showLogin: PropTypes.bool,
  showSubscribe: PropTypes.bool,
  showGiftGivingButton: PropTypes.bool,
  subscribeCtaText: PropTypes.string,
  subscribeUrl: PropTypes.string,
  username: PropTypes.string,
  manageMyAccountUrl: PropTypes.string,
  savedStoriesUrl: PropTypes.string,
  gsClientAdminUrl: PropTypes.string,
  mySubscriptionUrl: PropTypes.string,
  personalInfoUrl: PropTypes.string,
  billingUrl: PropTypes.string,
  newslettersAndPreferencesUrl: PropTypes.string,
  giftSubscriptionsUrl: PropTypes.string,
  helpUrl: PropTypes.string,
  isClientAdmin: PropTypes.bool,
  isGroupSubscriber: PropTypes.bool,
  fullName: PropTypes.string,
};

export default MastheadSecondary;
