// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import {LitElement, html, css} from 'lit-element';

import {connectStore} from 'reducers/base.js';
import * as userV0 from 'reducers/userV0.js';
import * as projectV0 from 'reducers/projectV0.js';
import * as sitewide from 'reducers/sitewide.js';

import {prpcClient} from 'prpc-client-instance.js';
import 'elements/framework/mr-keystrokes/mr-keystrokes.js';
import '../mr-dropdown/mr-dropdown.js';
import '../mr-dropdown/mr-account-dropdown.js';
import './mr-search-bar.js';

import {SHARED_STYLES} from 'shared/shared-styles.js';

import {logEvent} from 'monitoring/client-logger.js';

/**
 * @type {Object<string, string>} JS coding of enum values from
 *    appengine/monorail/api/v3/api_proto/project_objects.proto.
 */
const projectRoles = Object.freeze({
  OWNER: 'Owner',
  MEMBER: 'Member',
  CONTRIBUTOR: 'Contributor',
  NONE: '',
});

/**
 * `<mr-header>`
 *
 * The header for Monorail.
 *
 */
export class MrHeader extends connectStore(LitElement) {
  /** @override */
  static get styles() {
    return [
      SHARED_STYLES,
      css`
        :host {
          color: var(--chops-header-text-color);
          box-sizing: border-box;
          background: hsl(221, 67%, 92%);
          width: 100%;
          height: var(--monorail-header-height);
          display: flex;
          flex-direction: row;
          justify-content: flex-start;
          align-items: center;
          z-index: 800;
          background-color: var(--chops-primary-header-bg);
          border-bottom: var(--chops-normal-border);
          top: 0;
          position: fixed;
          padding: 0 4px;
          font-size: var(--chops-large-font-size);
        }
        @media (max-width: 840px) {
          :host {
            position: static;
          }
        }
        a {
          font-size: inherit;
          color: var(--chops-link-color);
          text-decoration: none;
          display: flex;
          align-items: center;
          justify-content: center;
          height: 100%;
          padding: 0 4px;
          flex-grow: 0;
          flex-shrink: 0;
        }
        a[hidden] {
          display: none;
        }
        a.button {
          font-size: inherit;
          height: auto;
          margin: 0 8px;
          border: 0;
          height: 30px;
        }
        .home-link {
          color: var(--chops-gray-900);
          letter-spacing: 0.5px;
          font-size: 18px;
          font-weight: 400;
          display: flex;
          font-stretch: 100%;
          padding-left: 8px;
        }
        a.home-link img {
          /** Cover up default padding with the custom logo. */
          margin-left: -8px;
        }
        a.home-link:hover {
          text-decoration: none;
        }
        mr-search-bar {
          margin-left: 8px;
          flex-grow: 2;
          max-width: 1000px;
        }
        i.material-icons {
          font-size: var(--chops-icon-font-size);
          color: var(--chops-primary-icon-color);
        }
        i.material-icons[hidden] {
          display: none;
        }
        .right-section {
          font-size: inherit;
          display: flex;
          align-items: center;
          height: 100%;
          margin-left: auto;
          justify-content: flex-end;
        }
        .hamburger-icon:hover {
          text-decoration: none;
        }
      `,
    ];
  }

  /** @override */
  render() {
    return this.projectName ?
        this._renderProjectScope() : this._renderNonProjectScope();
  }

  /**
   * @return {TemplateResult}
   */
  _renderProjectScope() {
    return html`
      <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
      <mr-keystrokes
        .issueId=${this.queryParams.id}
        .queryParams=${this.queryParams}
        .issueEntryUrl=${this.issueEntryUrl}
      ></mr-keystrokes>
      <a href="/p/${this.projectName}/issues/list" class="home-link">
        ${this.projectThumbnailUrl ? html`
          <img
            class="project-logo"
            src=${this.projectThumbnailUrl}
            title=${this.projectName}
          />
        ` : this.projectName}
      </a>
      <mr-dropdown
        class="project-selector"
        .text=${this.projectName}
        .items=${this._projectDropdownItems}
        menuAlignment="left"
        title=${this.presentationConfig.projectSummary}
      ></mr-dropdown>
      <a class="button emphasized new-issue-link" href=${this.issueEntryUrl}>
        New issue
      </a>
      <mr-search-bar
        .projectName=${this.projectName}
        .userDisplayName=${this.userDisplayName}
        .projectSavedQueries=${this.presentationConfig.savedQueries}
        .initialCan=${this._currentCan}
        .initialQuery=${this._currentQuery}
        .queryParams=${this.queryParams}
      ></mr-search-bar>

      <div class="right-section">
        <mr-dropdown
          icon="settings"
          label="Project Settings"
          .items=${this._projectSettingsItems}
        ></mr-dropdown>

        ${this._renderAccount()}
      </div>
    `;
  }

  /**
   * @return {TemplateResult}
   */
  _renderNonProjectScope() {
    return html`
      <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
      <a class="hamburger-icon" title="Main menu" hidden>
        <i class="material-icons">menu</i>
      </a>
      ${this._headerTitle ?
          html`<span class="home-link">${this._headerTitle}</span>` :
          html`<a href="/" class="home-link">avm99963 bugs</a>`}

      <div class="right-section">
        ${this._renderAccount()}
      </div>
    `;
  }

  /**
   * @return {TemplateResult}
   */
  _renderAccount() {
    if (!this.userDisplayName) {
      return html`<a href=${this.loginUrl}>Sign in</a>`;
    }

    return html`
      <mr-account-dropdown
        .userDisplayName=${this.userDisplayName}
        .logoutUrl=${this.logoutUrl}
        .loginUrl=${this.loginUrl}
      ></mr-account-dropdown>
    `;
  }

  /** @override */
  static get properties() {
    return {
      loginUrl: {type: String},
      logoutUrl: {type: String},
      projectName: {type: String},
      // Project thumbnail is set separately from presentationConfig to prevent
      // "flashing" logo when navigating EZT pages.
      projectThumbnailUrl: {type: String},
      userDisplayName: {type: String},
      isSiteAdmin: {type: Boolean},
      userProjects: {type: Object},
      presentationConfig: {type: Object},
      queryParams: {type: Object},
      // TODO(zhangtiff): Change this to be dynamically computed by the
      //   frontend with logic similar to ComputeIssueEntryURL().
      issueEntryUrl: {type: String},
      clientLogger: {type: Object},
      _headerTitle: {type: String},
      _currentQuery: {type: String},
      _currentCan: {type: String},
    };
  }

  /** @override */
  constructor() {
    super();

    this.presentationConfig = {};
    this.userProjects = {};
    this.isSiteAdmin = false;

    this._headerTitle = '';
  }

  /** @override */
  stateChanged(state) {
    this.projectName = projectV0.viewedProjectName(state);

    this.userProjects = userV0.projects(state);

    const currentUser = userV0.currentUser(state);
    this.isSiteAdmin = currentUser ? currentUser.isSiteAdmin : false;

    const presentationConfig = projectV0.viewedPresentationConfig(state);
    this.presentationConfig = presentationConfig;
    // Set separately in order allow EZT pages to load project logo before
    // the GetPresentationConfig pRPC request.
    this.projectThumbnailUrl = presentationConfig.projectThumbnailUrl;

    this._headerTitle = sitewide.headerTitle(state);

    this._currentQuery = sitewide.currentQuery(state);
    this._currentCan = sitewide.currentCan(state);

    this.queryParams = sitewide.queryParams(state);
  }

  /**
   * @return {boolean} whether the currently logged in user has admin
   *   privileges for the currently viewed project.
   */
  get canAdministerProject() {
    if (!this.userDisplayName) return false; // Not logged in.
    if (this.isSiteAdmin) return true;
    if (!this.userProjects || !this.userProjects.ownerOf) return false;
    return this.userProjects.ownerOf.includes(this.projectName);
  }

  /**
   * @return {string} The name of the role the user has in the viewed project.
   */
  get roleInCurrentProject() {
    if (!this.userProjects || !this.projectName) return projectRoles.NONE;
    const {ownerOf = [], memberOf = [], contributorTo = []} = this.userProjects;

    if (ownerOf.includes(this.projectName)) return projectRoles.OWNER;
    if (memberOf.includes(this.projectName)) return projectRoles.MEMBER;
    if (contributorTo.includes(this.projectName)) {
      return projectRoles.CONTRIBUTOR;
    }

    return projectRoles.NONE;
  }

  // TODO(crbug.com/monorail/6891): Remove once we deprecate the old issue
  // filing wizard.
  /**
   * @return {string} A URL for the page the issue filing wizard posts to.
   */
  get _wizardPostUrl() {
    // The issue filing wizard posts to the legacy issue entry page's ".do"
    // endpoint.
    return `${this._origin}/p/${this.projectName}/issues/entry.do`;
  }

  /**
   * @return {string} The domain name of the current page.
   */
  get _origin() {
    return window.location.origin;
  }

  /**
   * Computes the URL the user should see to a file an issue, accounting
   * for the case where a project has a customIssueEntryUrl to navigate to
   * the wizard as well.
   * @return {string} The URL that "New issue" button goes to.
   */
  get issueEntryUrl() {
    const config = this.presentationConfig;
    const role = this.roleInCurrentProject;
    const mayBeRedirectedToWizard = role === projectRoles.NONE;
    if (!this.userDisplayName || !config || !config.customIssueEntryUrl ||
        !mayBeRedirectedToWizard) {
      return `/p/${this.projectName}/issues/entry`;
    }

    const token = prpcClient.token;

    const customUrl = this.presentationConfig.customIssueEntryUrl;

    return `${customUrl}?token=${token}&role=${
      role}&continue=${this._wizardPostUrl}`;
  }

  /**
   * @return {Array<MenuItem>} the dropdown items for the project selector,
   *   showing which projects a user can switch to.
   */
  get _projectDropdownItems() {
    const {userProjects, loginUrl} = this;
    if (!this.userDisplayName) {
      return [{text: 'Sign in to see your projects', url: loginUrl}];
    }

    const items = [];
    const starredProjects = userProjects.starredProjects || [];
    const projects = (userProjects.ownerOf || [])
        .concat(userProjects.memberOf || [])
        .concat(userProjects.contributorTo || []);

    if (projects.length) {
      projects.sort();
      items.push({text: 'My Projects', separator: true});

      projects.forEach((project) => {
        items.push({text: project, url: `/p/${project}/issues/list`});
      });
    }

    if (starredProjects.length) {
      starredProjects.sort();
      items.push({text: 'Starred Projects', separator: true});

      starredProjects.forEach((project) => {
        items.push({text: project, url: `/p/${project}/issues/list`});
      });
    }

    if (items.length) {
      items.push({separator: true});
    }

    items.push({text: 'All projects', url: '/hosting/'});
    items.forEach((item) => {
      item.handler = () => this._projectChangedHandler(item.url);
    });
    return items;
  }

  /**
   * @return {Array<MenuItem>} dropdown menu items to show in the project
   *   settings menu.
   */
  get _projectSettingsItems() {
    const {projectName, canAdministerProject} = this;
    const items = [
      {text: 'People', url: `/p/${projectName}/people/list`},
      {text: 'Development Process', url: `/p/${projectName}/adminIntro`},
      {text: 'History', url: `/p/${projectName}/updates/list`},
    ];

    if (canAdministerProject) {
      items.push({separator: true});
      items.push({text: 'Administer', url: `/p/${projectName}/admin`});
    }
    return items;
  }

  /**
   * Records Google Analytics events for when users change projects using
   * the selector.
   * @param {string} url which project URL the user is navigating to.
   */
  _projectChangedHandler(url) {
    // Just log it to GA and continue.
    logEvent('mr-header', 'project-change', url);
  }
}

customElements.define('mr-header', MrHeader);
