import React from 'react';
import PropTypes from 'prop-types';
import find from 'lodash/find';

const makeLink = (...parts) => parts.join('/').replace(/\/{2,}/, '/');

const SideBarListItem = ({ activeDoc, baseUrl, page, children, className = '' }) => {
  const { slug, title, link_url: linkUrl, link_external: linkExternal } = page;

  const isActiveDoc = slug === activeDoc ? 'active' : '';
  const isActiveSub = (children && find(page.children, { slug: activeDoc })) || false;

  return (
    <li className={(isActiveDoc || isActiveSub) && children ? 'subnav-expanded' : ''}>
      <a
        className={`${className} text-overflow ${isActiveDoc}`}
        href={linkUrl || makeLink(baseUrl, 'docs', slug)}
        target={linkExternal ? '_blank' : ''}
      >
        {(children || linkExternal) && (
          <span className={`fa fa-${linkExternal ? 'external-link-square external' : 'chevron-right'}`} />
        )}
        {title}
      </a>
      {children}
    </li>
  );
};

const SideBarList = ({ pages, className = '', ...props }) => (
  /**
   * @todo: some of the destructuring herein is _very_ confusing...
   */
  <ul className={className}>
    {pages.map(page => {
      const hasChildren = 'children' in page && page.children.length > 0;
      if (page.hidden) return '';
      if (hasChildren)
        return (
          <SideBarListItem {...props} key={`page-${page.slug}`} page={page}>
            <SideBarList {...props} className="subpages" pages={page.children} />
          </SideBarListItem>
        );
      if (className === 'subpages') props.className = 'subpage';
      return <SideBarListItem {...props} key={`page-${page.slug}`} page={page} />;
    })}
  </ul>
);

const SideBarSection = ({ activeDoc, baseUrl, title, pages }) => (
  /** @todo: This component is probably simple enough to be combined
   *         into the SideBarList or root SideBar component directly.
   */
  <React.Fragment>
    <h3>{title}</h3>
    <SideBarList {...{ activeDoc, baseUrl, pages }} />
  </React.Fragment>
);

const SideBar = ({ activeDoc, baseUrl, categories }) =>
  Array.isArray(categories) && (
    <React.Fragment>
      {categories.map(category => (
        <SideBarSection {...category} key={category.slug} activeDoc={activeDoc} baseUrl={baseUrl} />
      ))}
    </React.Fragment>
  );

SideBar.propTypes = {
  /**
   * Slug for the current page.
   */
  activeDoc: PropTypes.string,
  /**
   * Project's generated base URL.
   */
  baseUrl: PropTypes.string,
  /**
   * Collection of ReadMe docs or endpoint reference pages.
   */
  categories: PropTypes.array,
};

SideBarSection.propTypes = {
  activeDoc: PropTypes.string,
  baseUrl: PropTypes.string,
  pages: PropTypes.array,
  title: PropTypes.string,
};

SideBarList.propTypes = {
  activeDoc: PropTypes.string,
  baseUrl: PropTypes.string,
  className: PropTypes.string,
  pages: PropTypes.array,
};

SideBarListItem.propTypes = {
  activeDoc: PropTypes.string,
  baseUrl: PropTypes.string,
  page: PropTypes.object,
};

export default SideBar;
