/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

const classNames = require('classnames');
const path = require('path');
const React = require('react');
const url = require('url');

const Container = require('./Container.js');
const Doc = require('./Doc.js');
const DocsSidebar = require('./DocsSidebar.js');
const OnPageNav = require('./nav/OnPageNav.js');
const Site = require('./Site.js');
const translation = require('../server/translation.js');
const docs = require('../server/docs.js');
const {idx, getGitLastUpdatedTime, getGitLastUpdatedBy} = require('./utils.js');

// component used to generate whole webpage for docs, including sidebar/header/footer
class DocsLayout extends React.Component {
  getRelativeURL = (from, to) => {
    const extension = this.props.config.cleanUrl ? '' : '.html';
    const relativeHref = path
      .relative(`${from}.html`, `${to}.html`)
      .replace('\\', '/')
      .replace(/^\.\.\//, '')
      .replace(/\.html$/, extension);
    return url.resolve(
      `${this.props.config.baseUrl}${this.props.metadata.permalink}`,
      relativeHref,
    );
  };

  render() {
    const metadata = this.props.metadata;
    const content = this.props.children;
    const i18n = translation[metadata.language];
    const id = metadata.localized_id;
    const defaultTitle = metadata.title;
    let DocComponent = Doc;

    if (this.props.Doc) {
      DocComponent = this.props.Doc;
    }
    const filepath = docs.getFilePath(metadata);

    const updateTime = this.props.config.enableUpdateTime
      ? getGitLastUpdatedTime(filepath)
      : null;
    const updateAuthor = this.props.config.enableUpdateBy
      ? getGitLastUpdatedBy(filepath)
      : null;

    const title =
      idx(i18n, ['localized-strings', 'docs', id, 'title']) || defaultTitle;
    const hasOnPageNav = this.props.config.onPageNav === 'separate';

    const previousTitle =
      idx(i18n, [
        'localized-strings',
        'docs',
        metadata.previous_id,
        'sidebar_label',
      ]) ||
      idx(i18n, ['localized-strings', 'docs', metadata.previous_id, 'title']) ||
      idx(i18n, ['localized-strings', 'previous']) ||
      metadata.previous_title ||
      'Previous';
    const nextTitle =
      idx(i18n, [
        'localized-strings',
        'docs',
        metadata.next_id,
        'sidebar_label',
      ]) ||
      idx(i18n, ['localized-strings', 'docs', metadata.next_id, 'title']) ||
      idx(i18n, ['localized-strings', 'next']) ||
      metadata.next_title ||
      'Next';

    return (
      <Site
        config={this.props.config}
        className={classNames('sideNavVisible', {
          separateOnPageNav: hasOnPageNav,
        })}
        title={title}
        description={metadata.description || content.trim().split('\n')[0]}
        language={metadata.language}
        version={metadata.version}
        metadata={metadata}>
        <div className="docMainWrapper wrapper">
          <DocsSidebar
            collapsible={this.props.config.docsSideNavCollapsible}
            metadata={metadata}
          />
          <Container className="mainContainer docsContainer">
            <DocComponent
              metadata={metadata}
              content={content}
              config={this.props.config}
              source={metadata.source}
              hideTitle={metadata.hide_title}
              title={title}
              version={metadata.version}
              language={metadata.language}
            />
            {(updateTime || updateAuthor) && (
              <div className="docLastUpdate">
                <em>
                  Last updated
                  {updateTime && ` on ${updateTime}`}
                  {updateAuthor && ` by ${updateAuthor}`}
                </em>
              </div>
            )}

            <div className="docs-prevnext">
              {metadata.previous_id && (
                <a
                  className="docs-prev button"
                  href={this.getRelativeURL(
                    metadata.localized_id,
                    metadata.previous_id,
                  )}>
                  <span className="arrow-prev">← </span>
                  <span
                    className={
                      previousTitle.match(/[a-z][A-Z]/) &&
                      'function-name-prevnext'
                    }>
                    {previousTitle}
                  </span>
                </a>
              )}
              {metadata.next_id && (
                <a
                  className="docs-next button"
                  href={this.getRelativeURL(
                    metadata.localized_id,
                    metadata.next_id,
                  )}>
                  <span
                    className={
                      nextTitle.match(/[a-z][A-Z]/) && 'function-name-prevnext'
                    }>
                    {nextTitle}
                  </span>
                  <span className="arrow-next"> →</span>
                </a>
              )}
            </div>
          </Container>
          {hasOnPageNav && (
            <nav className="onPageNav">
              <OnPageNav rawContent={content} />
            </nav>
          )}
        </div>
      </Site>
    );
  }
}
module.exports = DocsLayout;
