/**
 * Copyright (c) 2017-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */

const CWD = process.cwd();

const React = require("react");
const fs = require("fs");
const siteConfig = require(CWD + "/siteConfig.js");
const translation = require("../../server/translation.js");

const ENABLE_TRANSLATION = fs.existsSync(CWD + "/languages.js");
const ENABLE_VERSIONING = fs.existsSync(CWD + "/versions.json");
let versions;
if (ENABLE_VERSIONING) {
  versions = require(CWD + "/versions.json");
}
require("../../server/readMetadata.js").generateDocsMetadata();
const Metadata = require("../metadata.js");

// language dropdown nav item for when translations are enabled
class LanguageDropDown extends React.Component {
  render() {
    const enabledLanguages = [];
    let currentLanguage = "English";
    // add all enabled languages to dropdown
    translation["languages"].map(lang => {
      if (lang.tag == this.props.language) {
        currentLanguage = lang.name;
      }
      if (lang.tag == this.props.language) {
        return;
      }
      enabledLanguages.push(
        <li key={lang.tag}>
          <a href={siteConfig.baseUrl + lang.tag}>
            {lang.name}
          </a>
        </li>
      );
    });
    // if no languages are enabled besides English, return null
    if (enabledLanguages.length < 1) {
      return null;
    }
    // add Crowdin project recruiting link
    if (siteConfig.recruitingLink) {
      enabledLanguages.push(
        <li key="recruiting">
          <a href={siteConfig.recruitingLink} target="_blank">
            Help Translate
          </a>
        </li>
      );
    }

    return (
      <span>
        <li>
          <a id="languages-menu" href="#">
            <img
              className="languages-icon"
              src={this.props.baseUrl + "img/language.svg"}
            />
            {currentLanguage}
          </a>
          <div id="languages-dropdown" className="hide">
            <ul id="languages-dropdown-items">
              {enabledLanguages}
            </ul>
          </div>
        </li>
        <script
          dangerouslySetInnerHTML={{
            __html: `
        const languagesMenuItem = document.getElementById("languages-menu");
        const languagesDropDown = document.getElementById("languages-dropdown");
        languagesMenuItem.addEventListener("click", function(){
          if(languagesDropDown.className == "hide") {
            languagesDropDown.className = "visible";
          } else {
            languagesDropDown.className = "hide";
          }
        });
      `
          }}
        />
      </span>
    );
  }
}

// header navbar used by all pages generated with docusaurus
class HeaderNav extends React.Component {
  constructor() {
    super();
    this.state = {
      slideoutActive: false
    };
  }
  // function to generate each header link, used with each object in siteConfig.headerLinks
  makeLinks(link) {
    let href;
    if (link.search && this.props.config.algolia) {
      // return algolia search bar
      return (
        <li className="navSearchWrapper reactNavSearchWrapper">
          <input id="search_input_react" type="text" placeholder="Search" />
        </li>
      );
    } else if (link.languages) {
      return (
        // return language dropdown
        <LanguageDropDown
          baseUrl={this.props.baseUrl}
          language={this.props.language}
        />
      );
    } else if (link.doc) {
      // set link to document with current page's language/version
      let id;
      if (!ENABLE_VERSIONING || this.props.version === "next") {
        id = this.props.language + "-" + link.doc;
      } else {
        id =
          this.props.language +
          "-version-" +
          (this.props.version || versions[0]) +
          "-" +
          link.doc;
      }
      if (!Metadata[id]) {
        throw new Error(
          "A headerLink is specified with a document that does not exist. No document exists with id: " +
            link.doc
        );
      }
      href = this.props.config.baseUrl + Metadata[id].permalink;
    } else if (link.page) {
      // set link to page with current page's language if appropriate
      if (fs.existsSync(CWD + "/pages/en/" + link.page + ".js")) {
        href =
          siteConfig.baseUrl + this.props.language + "/" + link.page + ".html";
      } else {
        href = siteConfig.baseUrl + link.page + ".html";
      }
    } else if (link.href) {
      // set link to specified href
      href = link.href;
    } else if (link.blog) {
      // set link to blog url
      href = this.props.baseUrl + "blog";
    }
    return (
      <li>
        <a href={href} target={link.external ? "_blank" : "_self"}>
          {translation[this.props.language]
            ? translation[this.props.language]["localized-strings"][link.label]
            : link.label}
        </a>
      </li>
    );
  }

  render() {
    const versionsLink =
      this.props.baseUrl +
      (ENABLE_TRANSLATION
        ? this.props.language + "/versions.html"
        : "versions.html");
    return (
      <div className="fixedHeaderContainer">
        <div className="headerWrapper wrapper">
          <header>
            <a href={this.props.baseUrl}>
              <img src={this.props.baseUrl + siteConfig.headerIcon} />
              {!this.props.config.disableHeaderTitle &&
                <h2>
                  {this.props.title}
                </h2>}
            </a>
            {ENABLE_VERSIONING &&
              <a href={versionsLink}>
                <h3>
                  {this.props.version || versions[0]}
                </h3>
              </a>}
            {this.renderResponsiveNav()}
          </header>
        </div>
      </div>
    );
  }

  renderResponsiveNav() {
    const headerLinks = this.props.config.headerLinks;
    // add language drop down to end if location not specified
    let languages = false;
    headerLinks.forEach(link => {
      if (link.languages) {
        languages = true;
      }
    });
    if (!languages) {
      headerLinks.push({ languages: true });
    }
    // add search bar to end if location not specified
    let search = false;
    headerLinks.forEach(link => {
      if (link.search) {
        search = true;
      }
    });
    if (!search && this.props.config.algolia) {
      headerLinks.push({ search: true });
    }
    return (
      <div className="navigationWrapper navigationSlider">
        <nav className="slidingNav">
          <ul className="nav-site nav-site-internal">
            {headerLinks.map(this.makeLinks, this)}
          </ul>
        </nav>
      </div>
    );
  }
}

module.exports = HeaderNav;