/**
 * @license
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import '@polymer/iron-input/iron-input';
import '../../../styles/gr-form-styles';
import '../../shared/gr-button/gr-button';
import {ServerInfo, AccountDetailInfo} from '../../../types/common';
import {EditableAccountField} from '../../../constants/constants';
import {getAppContext} from '../../../services/app-context';
import {fireEvent} from '../../../utils/event-util';
import {LitElement, css, html, PropertyValues} from 'lit';
import {customElement, property, query, state} from 'lit/decorators';
import {sharedStyles} from '../../../styles/shared-styles';
import {formStyles} from '../../../styles/gr-form-styles';
import {when} from 'lit/directives/when';
import {ifDefined} from 'lit/directives/if-defined';
import {BindValueChangeEvent} from '../../../types/events';

declare global {
  interface HTMLElementTagNameMap {
    'gr-registration-dialog': GrRegistrationDialog;
  }
}

@customElement('gr-registration-dialog')
export class GrRegistrationDialog extends LitElement {
  /**
   * Fired when account details are changed.
   *
   * @event account-detail-update
   */

  /**
   * Fired when the close button is pressed.
   *
   * @event close
   */
  @query('#name') nameInput?: HTMLInputElement;

  @query('#username') usernameInput?: HTMLInputElement;

  @query('#displayName') displayName?: HTMLInputElement;

  @property() settingsUrl?: string;

  @state() account: Partial<AccountDetailInfo> = {};

  @state() loading = true;

  @state() saving = false;

  @state() serverConfig?: ServerInfo;

  @state() usernameMutable = false;

  @state() hasUsernameChange?: boolean;

  @state() username?: string;

  @state() nameMutable?: boolean;

  @state() hasNameChange?: boolean;

  @state() hasDisplayNameChange?: boolean;

  private readonly restApiService = getAppContext().restApiService;

  override connectedCallback() {
    super.connectedCallback();
    if (!this.getAttribute('role')) {
      this.setAttribute('role', 'dialog');
    }
  }

  static override styles = [
    sharedStyles,
    formStyles,
    css`
      :host {
        display: block;
      }
      main {
        max-width: 46em;
      }
      :host(.loading) main {
        display: none;
      }
      .loadingMessage {
        display: none;
        font-style: italic;
      }
      :host(.loading) .loadingMessage {
        display: block;
      }
      hr {
        margin-top: var(--spacing-l);
        margin-bottom: var(--spacing-l);
      }
      header {
        border-bottom: 1px solid var(--border-color);
        font-weight: var(--font-weight-bold);
        margin-bottom: var(--spacing-l);
      }
      .container {
        padding: var(--spacing-m) var(--spacing-xl);
      }
      footer {
        display: flex;
        justify-content: flex-end;
      }
      footer gr-button {
        margin-left: var(--spacing-l);
      }
      input {
        width: 20em;
      }
    `,
  ];

  override render() {
    return html`<div class="container gr-form-styles">
      <header>Please confirm your contact information</header>
      <div class="loadingMessage">Loading...</div>
      <main>
        <p>
          The following contact information was automatically obtained when you
          signed in to the site. This information is used to display who you are
          to others, and to send updates to code reviews you have either started
          or subscribed to.
        </p>
        <hr />
        <section>
          <span class="title">Full Name</span>
          ${when(
            this.nameMutable,
            () => html`<span class="value">
              <iron-input
                .bindValue=${this.account.name}
                @bind-value-changed=${(e: BindValueChangeEvent) => {
                  const oldAccount = this.account;
                  if (!oldAccount || oldAccount.name === e.detail.value) return;
                  this.account = {...oldAccount, name: e.detail.value};
                  this.hasNameChange = true;
                }}
              >
                <input id="name" ?disabled=${this.saving} />
              </iron-input>
            </span>`,
            () => html`<span class="value">${this.account.name}</span>`
          )}
        </section>
        <section>
          <span class="title">Display Name</span>
          <span class="value">
            <iron-input
              .bindValue=${this.account.display_name}
              @bind-value-changed=${(e: BindValueChangeEvent) => {
                const oldAccount = this.account;
                if (!oldAccount || oldAccount.display_name === e.detail.value) {
                  return;
                }
                this.account = {...oldAccount, display_name: e.detail.value};
                this.hasDisplayNameChange = true;
              }}
            >
              <input id="displayName" ?disabled=${this.saving} />
            </iron-input>
          </span>
        </section>
        ${when(
          this.computeUsernameEditable(),
          () => html`<section>
            <span class="title">Username</span>
            ${when(
              this.usernameMutable,
              () => html` <span class="value">
                <iron-input
                  .bindValue=${this.username}
                  @bind-value-changed=${(e: BindValueChangeEvent) => {
                    if (!this.usernameInput || this.username === e.detail.value)
                      return;
                    this.username = e.detail.value;
                    this.hasUsernameChange = true;
                  }}
                >
                  <input id="username" ?disabled=${this.saving} />
                </iron-input>
              </span>`,
              () => html`<span class="value">${this.username}</span>`
            )}
          </section>`
        )}
        <hr />
        <p>
          More configuration options for Gerrit may be found in the
          <a @click=${this.close} href=${ifDefined(this.settingsUrl)}
            >settings</a
          >.
        </p>
      </main>
      <footer>
        <gr-button
          id="closeButton"
          link
          ?disabled=${this.saving}
          @click=${this.handleClose}
          >Close</gr-button
        >
        <gr-button
          id="saveButton"
          primary
          link
          ?disabled=${this.computeSaveDisabled()}
          @click=${this.handleSave}
          >Save</gr-button
        >
      </footer>
    </div>`;
  }

  override willUpdate(changedProperties: PropertyValues) {
    if (changedProperties.has('account')) {
      this.usernameMutable = !this.account.username;
    }
    if (changedProperties.has('serverConfig')) {
      this.nameMutable = this.computeNameMutable();
    }
    if (changedProperties.has('loading')) {
      this.classList.toggle('loading', this.loading);
    }
  }

  loadData() {
    this.loading = true;

    const loadAccount = this.restApiService.getAccount().then(account => {
      if (!account) return;
      this.hasNameChange = false;
      this.hasUsernameChange = false;
      this.hasDisplayNameChange = false;
      // Provide predefined value for username to trigger computation of
      // username mutability.
      account.username = account.username || '';

      this.account = account;
      this.username = account.username;
    });

    const loadConfig = this.restApiService.getConfig().then(config => {
      this.serverConfig = config;
    });

    return Promise.all([loadAccount, loadConfig]).then(() => {
      this.loading = false;
    });
  }

  // private but used in test
  computeUsernameEditable() {
    return !!this.serverConfig?.auth.editable_account_fields.includes(
      EditableAccountField.USER_NAME
    );
  }

  private computeNameMutable() {
    return !!this.serverConfig?.auth.editable_account_fields.includes(
      EditableAccountField.FULL_NAME
    );
  }

  // private but used in test
  save() {
    this.saving = true;

    const promises = [];
    // Note that we are intentionally not acting on this._username being the
    // empty string (which is falsy).
    if (this.hasUsernameChange && this.usernameMutable && this.username) {
      promises.push(this.restApiService.setAccountUsername(this.username));
    }

    if (this.hasNameChange && this.nameMutable && this.account?.name) {
      promises.push(this.restApiService.setAccountName(this.account.name));
    }

    if (this.hasDisplayNameChange && this.account?.display_name) {
      promises.push(
        this.restApiService.setAccountDisplayName(this.account.display_name)
      );
    }

    return Promise.all(promises).then(() => {
      this.saving = false;
      fireEvent(this, 'account-detail-update');
    });
  }

  private handleSave(e: Event) {
    e.preventDefault();
    this.save().then(() => this.close());
  }

  private handleClose(e: Event) {
    e.preventDefault();
    this.close();
  }

  private close() {
    this.saving = true; // disable buttons indefinitely
    fireEvent(this, 'close');
  }

  // private but used in test
  computeSaveDisabled() {
    return (
      this.saving ||
      (!this.account?.display_name && !this.account.name && !this.username)
    );
  }
}
