// 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} from 'lit-element';
import {repeat} from 'lit-html/directives/repeat';
import page from 'page';
import qs from 'qs';

import {getServerStatusCron} from 'shared/cron.js';
import 'elements/framework/mr-site-banner/mr-site-banner.js';
import {store, connectStore} from 'reducers/base.js';
import * as projectV0 from 'reducers/projectV0.js';
import {hotlists} from 'reducers/hotlists.js';
import * as issueV0 from 'reducers/issueV0.js';
import * as permissions from 'reducers/permissions.js';
import * as users from 'reducers/users.js';
import * as userv0 from 'reducers/userV0.js';
import * as ui from 'reducers/ui.js';
import * as sitewide from 'reducers/sitewide.js';
import {arrayToEnglish} from 'shared/helpers.js';
import {trackPageChange} from 'shared/ga-helpers.js';
import 'elements/issue-list/mr-list-page/mr-list-page.js';
import 'elements/issue-entry/mr-issue-entry-page.js';
import 'elements/framework/mr-header/mr-header.js';
import 'elements/help/mr-cue/mr-cue.js';
import {cueNames} from 'elements/help/mr-cue/cue-helpers.js';
import 'elements/chops/chops-snackbar/chops-snackbar.js';

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

const QUERY_PARAMS_THAT_RESET_SCROLL = ['q', 'mode', 'id'];

/**
 * `<mr-app>`
 *
 * The container component for all pages under the Monorail SPA.
 *
 */
export class MrApp extends connectStore(LitElement) {
  /** @override */
  render() {
    if (this.page === 'wizard') {
      return html`<div id="reactMount"></div>`;
    }

    return html`
      <style>
        ${SHARED_STYLES}
        mr-app {
          display: block;
          padding-top: var(--monorail-header-height);
          margin-top: -1px; /* Prevent a double border from showing up. */

          /* From shared-styles.js. */
          --mr-edit-field-padding: 0.125em 4px;
          --mr-edit-field-width: 90%;
          --mr-input-grid-gap: 6px;
          font-family: var(--chops-font-family);
          color: var(--chops-primary-font-color);
          font-size: var(--chops-main-font-size);
        }
        main {
          border-top: var(--chops-normal-border);
        }
        .snackbar-container {
          position: fixed;
          bottom: 1em;
          left: 1em;
          display: flex;
          flex-direction: column;
          align-items: flex-start;
          z-index: 1000;
        }
        /** Unfix <chops-snackbar> to allow stacking. */
        chops-snackbar {
          position: static;
          margin-top: 0.5em;
        }
      </style>
      <mr-header
        .userDisplayName=${this.userDisplayName}
        .loginUrl=${this.loginUrl}
        .logoutUrl=${this.logoutUrl}
      ></mr-header>
      <mr-site-banner></mr-site-banner>
      <mr-cue
        cuePrefName=${cueNames.SWITCH_TO_PARENT_ACCOUNT}
        .loginUrl=${this.loginUrl}
        centered
        nondismissible
      ></mr-cue>
      <mr-cue
        cuePrefName=${cueNames.SEARCH_FOR_NUMBERS}
        centered
      ></mr-cue>
      <main>${this._renderPage()}</main>
      <div class="snackbar-container" aria-live="polite">
        ${repeat(this._snackbars, (snackbar) => html`
          <chops-snackbar
            @close=${this._closeSnackbar.bind(this, snackbar.id)}
          >${snackbar.text}</chops-snackbar>
        `)}
      </div>
    `;
  }

  /**
   * @param {string} id The name of the snackbar to close.
   */
  _closeSnackbar(id) {
    store.dispatch(ui.hideSnackbar(id));
  }

  /**
   * Helper for determiing which page component to render.
   * @return {TemplateResult}
   */
  _renderPage() {
    switch (this.page) {
      case 'detail':
        return html`
          <mr-issue-page
            .userDisplayName=${this.userDisplayName}
            .loginUrl=${this.loginUrl}
          ></mr-issue-page>
        `;
      case 'entry':
        return html`
          <mr-issue-entry-page
            .userDisplayName=${this.userDisplayName}
            .loginUrl=${this.loginUrl}
          ></mr-issue-entry-page>
        `;
      case 'grid':
        return html`
          <mr-grid-page
            .userDisplayName=${this.userDisplayName}
          ></mr-grid-page>
        `;
      case 'list':
        return html`
          <mr-list-page
            .userDisplayName=${this.userDisplayName}
          ></mr-list-page>
        `;
      case 'chart':
        return html`<mr-chart-page></mr-chart-page>`;
      case 'projects':
        return html`<mr-projects-page></mr-projects-page>`;
      case 'hotlist-issues':
        return html`<mr-hotlist-issues-page></mr-hotlist-issues-page>`;
      case 'hotlist-people':
        return html`<mr-hotlist-people-page></mr-hotlist-people-page>`;
      case 'hotlist-settings':
        return html`<mr-hotlist-settings-page></mr-hotlist-settings-page>`;
      default:
        return;
    }
  }

  /** @override */
  static get properties() {
    return {
      /**
       * Backend-generated URL for the page the user is directed to for login.
       */
      loginUrl: {type: String},
      /**
       * Backend-generated URL for the page the user is directed to for logout.
       */
      logoutUrl: {type: String},
      /**
       * The display name of the currently logged in user.
       */
      userDisplayName: {type: String},
      /**
       * The search parameters in the user's current URL.
       */
      queryParams: {type: Object},
      /**
       * A list of forms to check for "dirty" values when the user navigates
       * across pages.
       */
      dirtyForms: {type: Array},
      /**
       * App Engine ID for the current version being viewed.
       */
      versionBase: {type: String},
      /**
       * A String identifier for the page that the user is viewing.
       */
      page: {type: String},
      /**
       * A String for the title of the page that the user will see in their
       * browser tab. ie: equivalent to the <title> tag.
       */
      pageTitle: {type: String},
      /**
       * Array of snackbar objects to render.
       */
      _snackbars: {type: Array},
    };
  }

  /** @override */
  constructor() {
    super();
    this.queryParams = {};
    this.dirtyForms = [];
    this.userDisplayName = '';

    /**
     * @type {PageJS.Context}
     * The context of the page. This should not be a LitElement property
     * because we don't want to re-render when updating this.
     */
    this._lastContext = undefined;
  }

  /** @override */
  createRenderRoot() {
    return this;
  }

  /** @override */
  stateChanged(state) {
    this.dirtyForms = ui.dirtyForms(state);
    this.queryParams = sitewide.queryParams(state);
    this.pageTitle = sitewide.pageTitle(state);
    this._snackbars = ui.snackbars(state);
  }

  /** @override */
  updated(changedProperties) {
    if (changedProperties.has('userDisplayName') && this.userDisplayName) {
      // TODO(https://crbug.com/monorail/7238): Migrate userv0 calls to v3 API.
      store.dispatch(userv0.fetch(this.userDisplayName));

      // Typically we would prefer 'users/<userId>' instead.
      store.dispatch(users.fetch(`users/${this.userDisplayName}`));
    }

    if (changedProperties.has('pageTitle')) {
      // To ensure that changes to the page title are easy to reason about,
      // we want to sync the current pageTitle in the Redux state to
      // document.title in only one place in the code.
      document.title = this.pageTitle;
    }
    if (changedProperties.has('page')) {
      trackPageChange(this.page, this.userDisplayName);
    }
  }

  /** @override */
  connectedCallback() {
    super.connectedCallback();

    // TODO(zhangtiff): Figure out some way to save Redux state between
    // page loads.

    // page doesn't handle users reloading the page or closing a tab.
    window.onbeforeunload = this._confirmDiscardMessage.bind(this);

    // Start a cron task to periodically request the status from the server.
    getServerStatusCron.start();

    const postRouteHandler = this._postRouteHandler.bind(this);

    // Populate the project route parameter before _preRouteHandler runs.
    page('/p/:project/*', (_ctx, next) => next());
    page('*', this._preRouteHandler.bind(this));

    page('/hotlists/:hotlist', (ctx) => {
      page.redirect(`/hotlists/${ctx.params.hotlist}/issues`);
    });
    page('/hotlists/:hotlist/*', this._selectHotlist);
    page('/hotlists/:hotlist/issues',
        this._loadHotlistIssuesPage.bind(this), postRouteHandler);
    page('/hotlists/:hotlist/people',
        this._loadHotlistPeoplePage.bind(this), postRouteHandler);
    page('/hotlists/:hotlist/settings',
        this._loadHotlistSettingsPage.bind(this), postRouteHandler);

    // Handle Monorail's landing page.
    page('/p', '/');
    page('/projects', '/');
    page('/hosting', '/');
    page('/', this._loadProjectsPage.bind(this), postRouteHandler);

    page('/p/:project/issues/list', this._loadListPage.bind(this),
        postRouteHandler);
    page('/p/:project/issues/detail', this._loadIssuePage.bind(this),
        postRouteHandler);
    page('/p/:project/issues/entry_new', this._loadEntryPage.bind(this),
        postRouteHandler);
    page('/p/:project/issues/wizard', this._loadWizardPage.bind(this),
        postRouteHandler);

    // Redirects from old hotlist pages to SPA hotlist pages.
    const hotlistRedirect = (pageName) => async (ctx) => {
      const name =
          await hotlists.getHotlistName(ctx.params.user, ctx.params.hotlist);
      page.redirect(`/${name}/${pageName}`);
    };
    page('/users/:user/hotlists/:hotlist', hotlistRedirect('issues'));
    page('/users/:user/hotlists/:hotlist/people', hotlistRedirect('people'));
    page('/users/:user/hotlists/:hotlist/details', hotlistRedirect('settings'));

    page();
  }

  /**
   * Handler that runs on every single route change, before the new page has
   * loaded. This function should not use store.dispatch() or assign properties
   * on this because running these actions causes extra re-renders to happen.
   * @param {PageJS.Context} ctx A page.js Context containing routing state.
   * @param {function} next Passes execution on to the next registered callback.
   */
  _preRouteHandler(ctx, next) {
    // We're not really navigating anywhere, so don't do anything.
    if (this._lastContext && this._lastContext.path &&
      ctx.path === this._lastContext.path) {
      Object.assign(ctx, this._lastContext);
      // Set ctx.handled to false, so we don't push the state to browser's
      // history.
      ctx.handled = false;
      return;
    }

    // Check if there were forms with unsaved data before loading the next
    // page.
    const discardMessage = this._confirmDiscardMessage();
    if (discardMessage && !confirm(discardMessage)) {
      Object.assign(ctx, this._lastContext);
      // Set ctx.handled to false, so we don't push the state to browser's
      // history.
      ctx.handled = false;
      // We don't call next to avoid loading whatever page was supposed to
      // load next.
      return;
    }

    // Run query string parsing on all routes. Query params must be parsed
    // before routes are loaded because some routes use them to conditionally
    // load bundles.
    // Based on: https://visionmedia.github.io/page.js/#plugins
    const params = qs.parse(ctx.querystring);

    // Make sure queryParams are not case sensitive.
    const lowerCaseParams = {};
    Object.keys(params).forEach((key) => {
      lowerCaseParams[key.toLowerCase()] = params[key];
    });
    ctx.queryParams = lowerCaseParams;

    this._selectProject(ctx.params.project);

    next();
  }

  /**
   * Handler that runs on every single route change, after the new page has
   * loaded.
   * @param {PageJS.Context} ctx A page.js Context containing routing state.
   * @param {function} next Passes execution on to the next registered callback.
   */
  _postRouteHandler(ctx, next) {
    // Scroll to the requested element if a hash is present.
    if (ctx.hash) {
      store.dispatch(ui.setFocusId(ctx.hash));
    }

    // Sync queryParams to Redux after the route has loaded, rather than before,
    // to avoid having extra queryParams update on the previously loaded
    // component.
    store.dispatch(sitewide.setQueryParams(ctx.queryParams));

    // Increment the count of navigations in the Redux store.
    store.dispatch(ui.incrementNavigationCount());

    // Clear dirty forms when entering a new page.
    store.dispatch(ui.clearDirtyForms());


    if (!this._lastContext || this._lastContext.pathname !== ctx.pathname ||
        this._hasReleventParamChanges(ctx.queryParams,
            this._lastContext.queryParams)) {
      // Reset the scroll position after a new page has rendered.
      window.scrollTo(0, 0);
    }

    // Save the context of this page to be compared to later.
    this._lastContext = ctx;
  }

  /**
   * Finds if a route change changed query params in a way that should cause
   * scrolling to reset.
   * @param {Object} currentParams
   * @param {Object} oldParams
   * @param {Array<string>=} paramsToCompare Which params to check.
   * @return {boolean} Whether any of the relevant query params changed.
   */
  _hasReleventParamChanges(currentParams, oldParams,
      paramsToCompare = QUERY_PARAMS_THAT_RESET_SCROLL) {
    return paramsToCompare.some((paramName) => {
      return currentParams[paramName] !== oldParams[paramName];
    });
  }

  /**
   * Helper to manage syncing project route state to Redux.
   * @param {string=} project displayName for a referenced project.
   *   Defaults to null for consistency with Redux.
   */
  _selectProject(project = null) {
    if (projectV0.viewedProjectName(store.getState()) !== project) {
      // Note: We want to update the project even if the new project
      // is null.
      store.dispatch(projectV0.select(project));
      if (project) {
        store.dispatch(projectV0.fetch(project));
      }
    }
  }

  /**
   * Loads and triggers rendering for the list of all projects.
   * @param {PageJS.Context} ctx A page.js Context containing routing state.
   * @param {function} next Passes execution on to the next registered callback.
   */
  async _loadProjectsPage(ctx, next) {
    await import(/* webpackChunkName: "mr-projects-page" */
        '../projects/mr-projects-page/mr-projects-page.js');
    this.page = 'projects';
    next();
  }

  /**
   * Loads and triggers render for the issue detail page.
   * @param {PageJS.Context} ctx A page.js Context containing routing state.
   * @param {function} next Passes execution on to the next registered callback.
   */
  async _loadIssuePage(ctx, next) {
    performance.clearMarks('start load issue detail page');
    performance.mark('start load issue detail page');

    await import(/* webpackChunkName: "mr-issue-page" */
        '../issue-detail/mr-issue-page/mr-issue-page.js');

    const issueRef = {
      localId: Number.parseInt(ctx.queryParams.id),
      projectName: ctx.params.project,
    };
    store.dispatch(issueV0.viewIssue(issueRef));
    store.dispatch(issueV0.fetchIssuePageData(issueRef));
    this.page = 'detail';
    next();
  }

  /**
   * Loads and triggers render for the issue list page, including the list,
   * grid, and chart modes.
   * @param {PageJS.Context} ctx A page.js Context containing routing state.
   * @param {function} next Passes execution on to the next registered callback.
   */
  async _loadListPage(ctx, next) {
    performance.clearMarks('start load issue list page');
    performance.mark('start load issue list page');
    switch (ctx.queryParams && ctx.queryParams.mode &&
        ctx.queryParams.mode.toLowerCase()) {
      case 'grid':
        await import(/* webpackChunkName: "mr-grid-page" */
            '../issue-list/mr-grid-page/mr-grid-page.js');
        this.page = 'grid';
        break;
      case 'chart':
        await import(/* webpackChunkName: "mr-chart-page" */
            '../issue-list/mr-chart-page/mr-chart-page.js');
        this.page = 'chart';
        break;
      default:
        this.page = 'list';
        break;
    }
    next();
  }

  /**
   * Load the issue entry page
   * @param {PageJS.Context} ctx A page.js Context containing routing state.
   * @param {function} next Passes execution on to the next registered callback.
   */
  _loadEntryPage(ctx, next) {
    this.page = 'entry';
    next();
  }

  /**
   * Load the issue wizard
   * @param {PageJS.Context} ctx A page.js Context containing routing state.
   * @param {function} next Passes execution on to the next registered callback.
   */
  async _loadWizardPage(ctx, next) {
    const {renderWizard} = await import(
        /* webpackChunkName: "IssueWizard" */ '../../react/IssueWizard.tsx');

    this.page = 'wizard';
    next();

    await this.updateComplete;

    const mount = document.getElementById('reactMount');

    renderWizard(mount);
  }

  /**
   * Gets the currently viewed HotlistRef from the URL, selects
   * it in the Redux store, and fetches the Hotlist data.
   * @param {PageJS.Context} ctx A page.js Context containing routing state.
   * @param {function} next Passes execution on to the next registered callback.
   */
  _selectHotlist(ctx, next) {
    const name = 'hotlists/' + ctx.params.hotlist;
    store.dispatch(hotlists.select(name));
    store.dispatch(hotlists.fetch(name));
    store.dispatch(hotlists.fetchItems(name));
    store.dispatch(permissions.batchGet([name]));
    next();
  }

  /**
   * Loads mr-hotlist-issues-page.js and makes it the currently viewed page.
   * @param {PageJS.Context} ctx A page.js Context containing routing state.
   * @param {function} next Passes execution on to the next registered callback.
   */
  async _loadHotlistIssuesPage(ctx, next) {
    await import(/* webpackChunkName: "mr-hotlist-issues-page" */
        `../hotlist/mr-hotlist-issues-page/mr-hotlist-issues-page.js`);
    this.page = 'hotlist-issues';
    next();
  }

  /**
   * Loads mr-hotlist-people-page.js and makes it the currently viewed page.
   * @param {PageJS.Context} ctx A page.js Context containing routing state.
   * @param {function} next Passes execution on to the next registered callback.
   */
  async _loadHotlistPeoplePage(ctx, next) {
    await import(/* webpackChunkName: "mr-hotlist-people-page" */
        `../hotlist/mr-hotlist-people-page/mr-hotlist-people-page.js`);
    this.page = 'hotlist-people';
    next();
  }

  /**
   * Loads mr-hotlist-settings-page.js and makes it the currently viewed page.
   * @param {PageJS.Context} ctx A page.js Context containing routing state.
   * @param {function} next Passes execution on to the next registered callback.
   */
  async _loadHotlistSettingsPage(ctx, next) {
    await import(/* webpackChunkName: "mr-hotlist-settings-page" */
        `../hotlist/mr-hotlist-settings-page/mr-hotlist-settings-page.js`);
    this.page = 'hotlist-settings';
    next();
  }

  /**
   * Constructs a message to warn users about dirty forms when they navigate
   * away from a page, to prevent them from loasing data.
   * @return {string} Message shown to users to warn about in flight form
   *   changes.
   */
  _confirmDiscardMessage() {
    if (!this.dirtyForms.length) return null;
    const dirtyFormsMessage =
      'Discard your changes in the following forms?\n' +
      arrayToEnglish(this.dirtyForms);
    return dirtyFormsMessage;
  }
}

customElements.define('mr-app', MrApp);
