/**
 * @license
 * Copyright (C) 2019 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 {customElement, property, query, state} from 'lit/decorators.js';
import {css, CSSResult, html, LitElement} from 'lit';
import {PluginApi} from '@gerritcodereview/typescript-api/plugin';
import {RestPluginApi} from '@gerritcodereview/typescript-api/rest';
import {GroupInfo} from '@gerritcodereview/typescript-api/rest-api';

import {AccountCapabilityInfo} from './plugin';
import {ConfigInfo, ServiceUserInfo} from './gr-serviceuser-create';
import {GrServiceUserSshPanel} from './gr-serviceuser-ssh-panel';
import {GrServiceUserTokens} from './gr-serviceuser-tokens';

import './gr-serviceuser-ssh-panel';
import './gr-serviceuser-tokens';

const NOT_FOUND_MESSAGE = 'Not Found';

@customElement('gr-serviceuser-detail')
export class GrServiceUserDetail extends LitElement {
  @query('#sshEditor')
  sshEditor!: GrServiceUserSshPanel;

  @query('#httpPass')
  httpPass!: GrServiceUserTokens;

  @query('#serviceUserFullNameInput')
  serviceUserFullNameInput!: HTMLInputElement;

  @query('#serviceUserEmailInput')
  serviceUserEmailInput!: HTMLInputElement;

  @query('#serviceUserOwnerInput')
  serviceUserOwnerInput!: HTMLInputElement;

  @property({type: Object})
  plugin!: PluginApi;

  @property()
  pluginRestApi!: RestPluginApi;

  @property({type: String})
  serviceUserId?: String;

  @property({type: Object})
  serviceUser!: ServiceUserInfo;

  @state()
  loading = true;

  @state()
  statusButtonText = 'Activate';

  @state()
  prefsChanged = false;

  @state()
  changingPrefs = false;

  @state()
  isAdmin = false;

  @state()
  emailAllowed = false;

  @state()
  ownerAllowed = false;

  @state()
  httpPasswordAllowed = false;

  @property({type: String})
  fullName?: String;

  @property({type: String})
  email = '';

  @property({type: Array})
  availableOwners?: Array<GroupInfo>;

  @property({type: String})
  owner = NOT_FOUND_MESSAGE;

  @property({type: String})
  ownerChangeWarning?: String;

  override connectedCallback() {
    super.connectedCallback();
    this.pluginRestApi = this.plugin.restApi();
  }

  override firstUpdated() {
    this.extractUserId();
    this.loadServiceUser();
  }

  static override get styles() {
    return [
      window.Gerrit.styles.font as CSSResult,
      window.Gerrit.styles.form as CSSResult,
      window.Gerrit.styles.subPage as CSSResult,
      css`
        main {
          margin: 2em auto;
          max-width: 50em;
        }

        .heading {
          font-size: x-large;
          font-weight: 500;
        }

        h1#Title {
          margin-bottom: 1em;
        }

        p#ownerChangeWarning {
          margin-top: 1em;
          margin-bottom: 1em;
        }

        span#gr_serviceuser_activity {
          border-radius: 1em;
          width: 10em;
          padding: 0.3em;
          font-weight: bold;
          text-align: center;
        }

        span.value {
          width: 50%;
        }

        input.wide {
          width: var(--paper-input-container-shared-input-style_-_width);
        }

        span.Active {
          background-color: #9fcc6b;
        }

        span.Inactive {
          background-color: #f7a1ad;
        }
      `,
    ];
  }

  override render() {
    return html`
      <main class="gr-form-styles read-only">
        <div id="loading" class="${this.computeLoadingClass()}">Loading...</div>
        <div id="loadedContent" class="${this.computeLoadingClass()}">
          <h1 id="Title" class="heading">
            Service User "${this.serviceUser?.name}"
          </h1>
          <div id="form">
            <fieldset>
              <fieldset>
                <h2 id="accountState" class="heading-2">Account State</h2>
                <section>
                  <span class="title">Current State</span>
                  <span
                    id="gr_serviceuser_activity"
                    class="value ${this.active()}"
                  >
                    ${this.active()}
                  </span>
                </section>
                <gr-button
                  id="statusToggleButton"
                  @click="${this.toggleStatus}"
                  ?disabled="${this.loading}"
                >
                  ${this.statusButtonText}
                </gr-button>
              </fieldset>
              <fieldset>
                <h2 id="userDataHeader" class="heading-2">User Data</h2>
                <section>
                  <span class="title">Username</span>
                  <span class="value">${this.serviceUser?.username}</span>
                </section>
                ${this.renderFullNameFormSection()}
                <section>
                  <span class="title">Email Address</span>
                  <span class="value"> ${this.renderEmailFormContent()} </span>
                </section>
                <section>
                  <span class="title">Owner Group</span>
                  <span class="value">
                    ${this.renderOwnerGroupFormContent()}
                  </span>
                </section>
                <p id="ownerChangeWarning" class="style-scope gr-settings-view">
                  ${this.ownerChangeWarning}
                </p>
                <gr-button
                  id="savePrefs"
                  @click="${this.handleSavePreferences}"
                  ?disabled="${!this.prefsChanged}"
                >
                  Save changes
                </gr-button>
              </fieldset>
              <fieldset>
                <h2 id="creationHeader" class="heading-2">Creation</h2>
                <section>
                  <span class="title">Created By</span>
                  <span class="value">${this.getCreator()}</span>
                </section>
                <section>
                  <span class="title">Created At</span>
                  <span class="value">${this.serviceUser?.created_at}</span>
                </section>
              </fieldset>
              <fieldset>
                <h2 id="credentialsHeader" class="heading-2">Credentials</h2>
                ${this.renderHttpCredentialsForm()}
                <fieldset>
                  <h3 id="SSHKeys">SSH keys</h3>
                  <gr-serviceuser-ssh-panel
                    id="sshEditor"
                  ></gr-serviceuser-ssh-panel>
                </fieldset>
              </fieldset>
            </fieldset>
          </div>
        </div>
      </main>
    `;
  }

  private renderFullNameFormSection() {
    return html`
      <section>
        <span class="title">Full Name</span>
        <span class="value">
          <input
            id="serviceUserFullNameInput"
            type="text"
            class="wide"
            .value="${this.fullName}"
            .placeholder="${this.serviceUser?.name}"
            ?disabled="${this.changingPrefs}"
            @input="${this.fullNameChanged}"
          />
        </span>
      </section>
    `;
  }

  private renderEmailFormContent() {
    if (this.emailAllowed) {
      return html`
        <input
          id="serviceUserEmailInput"
          type="text"
          class="wide"
          .value="${this.email}"
          .placeholder="${this.serviceUser.email ?? ''}"
          ?disabled="${this.changingPrefs}"
          @input="${this.emailChanged}"
        />
      `;
    }

    return html`${this.serviceUser?.email}`;
  }

  private renderOwnerGroupFormContent() {
    if (this.ownerAllowed) {
      return html`
        <gr-autocomplete
          id="serviceUserOwnerInput"
          .text="${this.owner}"
          .value="${this.owner}"
          .query="${(input: string) => this.getGroupSuggestions(input)}"
          ?disabled="${this.changingPrefs}"
          @value-changed="${this.ownerChanged}"
          @text-changed="${this.ownerChanged}"
        >
          ${this.getCurrentOwnerGroup()}
        </gr-autocomplete>
      `;
    }

    return html`${this.getCurrentOwnerGroup()}`;
  }

  private renderHttpCredentialsForm() {
    if (this.httpPasswordAllowed) {
      return html`
        <fieldset>
          <h3 id="HTTPCredentials">HTTP Credentials</h3>
          <fieldset>
            <gr-serviceuser-tokens id="httpPass">
              </gr-http-password>
          </fieldset>
        </fieldset>
      `;
    }

    return html``;
  }

  private loadServiceUser() {
    if (!this.serviceUserId) {
      return;
    }

    const promises = [];

    promises.push(this.getPluginConfig());
    promises.push(this.getServiceUser());

    Promise.all(promises).then(() => {
      this.sshEditor.loadData(this.pluginRestApi);
      if (this.httpPasswordAllowed) {
        this.httpPass.loadData(this.pluginRestApi);
      }

      this.dispatchEvent(
        new CustomEvent('title-change', {
          detail: {title: this.serviceUser?.name},
          bubbles: true,
          composed: true,
        })
      );
      this.computeStatusButtonText();
      this.loading = false;
      this.fullName = this.serviceUser?.name;
      this.email = this.serviceUser.email ?? '';
      this.owner = this.getCurrentOwnerGroup() ?? NOT_FOUND_MESSAGE;
    });
  }

  private computeLoadingClass() {
    return this.loading ? 'loading' : '';
  }

  private extractUserId() {
    this.serviceUserId = this.baseURI.split('/').pop();
  }

  private getPermissions() {
    return this.pluginRestApi
      .get<AccountCapabilityInfo>('/accounts/self/capabilities/')
      .then(capabilities => {
        if (!capabilities) {
          this.isAdmin = false;
        } else {
          this.isAdmin =
            capabilities.administrateServer === undefined ? false : true;
        }
      });
  }

  private getPluginConfig() {
    return this.getPermissions()
      .then(() =>
        this.pluginRestApi.get<ConfigInfo>('/config/server/serviceuser~config/')
      )
      .then(config => {
        if (!config) {
          return;
        }
        this.emailAllowed = config.allow_email || this.isAdmin;
        this.ownerAllowed = config.allow_owner || this.isAdmin;
        this.httpPasswordAllowed = config.allow_http_password || this.isAdmin;
      });
  }

  private getServiceUser() {
    return this.pluginRestApi
      .get(`/a/config/server/serviceuser~serviceusers/${this.serviceUserId}`)
      .then(serviceUser => {
        if (!serviceUser) {
          this.serviceUser = {};
          return;
        }
        this.serviceUser = serviceUser;
      });
  }

  private active() {
    if (!this.serviceUser) {
      return NOT_FOUND_MESSAGE;
    }

    return this.serviceUser?.inactive === true ? 'Inactive' : 'Active';
  }

  private computeStatusButtonText() {
    if (!this.serviceUser) {
      return;
    }

    this.statusButtonText =
      this.serviceUser?.inactive === true ? 'Activate' : 'Deactivate';
  }

  private toggleStatus() {
    if (this.serviceUser?.inactive === true) {
      this.pluginRestApi
        .put(
          `/config/server/serviceuser~serviceusers/${this.serviceUser?._account_id}/active`
        )
        .then(() => {
          this.loadServiceUser();
        });
    } else {
      this.pluginRestApi
        .delete(
          `/config/server/serviceuser~serviceusers/${this.serviceUser?._account_id}/active`
        )
        .then(() => {
          this.loadServiceUser();
        });
    }
  }

  private getCreator() {
    if (!this.serviceUser || !this.serviceUser?.created_by) {
      return NOT_FOUND_MESSAGE;
    }

    if (this.serviceUser?.created_by.username !== undefined) {
      return this.serviceUser?.created_by.username;
    }

    if (this.serviceUser?.created_by._account_id !== -1) {
      return this.serviceUser?.created_by._account_id;
    }

    return NOT_FOUND_MESSAGE;
  }

  private getCurrentOwnerGroup() {
    return this.serviceUser && this.serviceUser?.owner
      ? this.serviceUser?.owner.name
      : NOT_FOUND_MESSAGE;
  }

  private isNewValidEmail(email: String) {
    if (!this.serviceUser.email) {
      return email.includes('@');
    }
    return email !== this.serviceUser.email && (email.includes('@') || email.length === 0);
  }

  private getGroupSuggestions(input: String) {
    return this.pluginRestApi
      .get<Object>(`/a/groups/?n=10&suggest=${input}`)
      .then(response => {
        this.availableOwners = Object.values(response);
        return Object.keys(response).map(name => {
          return {name, value: name};
        });
      });
  }

  private isNewOwner() {
    if (this.owner === NOT_FOUND_MESSAGE) {
      return false;
    }
    return this.owner !== this.getCurrentOwnerGroup();
  }

  private computeOwnerWarning() {
    let message = 'If ';
    message +=
      this.getCurrentOwnerGroup() !== NOT_FOUND_MESSAGE
        ? 'the owner group is changed'
        : 'an owner group is set';
    message += ' only members of the ';
    message += this.getCurrentOwnerGroup() !== NOT_FOUND_MESSAGE ? 'new ' : '';
    message += 'owner group can see and administrate the service user.';
    message +=
      this.getCurrentOwnerGroup() !== NOT_FOUND_MESSAGE
        ? ''
        : ' The creator of the service user can no' +
          ' longer see and administrate the service user if she/he' +
          ' is not member of the owner group.';
    this.ownerChangeWarning = message;
  }

  private fullNameChanged() {
    this.fullName = this.serviceUserFullNameInput.value;
    this.computePrefsChanged();
  }

  private emailChanged() {
    this.email = this.serviceUserEmailInput.value;
    this.computePrefsChanged();
  }

  private ownerChanged() {
    this.owner = this.serviceUserOwnerInput.value;

    if (this.isNewOwner()) {
      this.computeOwnerWarning();
    }

    this.computePrefsChanged();
  }

  private computePrefsChanged() {
    if (this.loading || this.changingPrefs) {
      return;
    }

    if (
      this.owner === this.getCurrentOwnerGroup() &&
      !this.isNewValidEmail(this.email) &&
      this.fullName === this.serviceUser.name
    ) {
      this.prefsChanged = false;
      return;
    }

    this.prefsChanged = true;
  }

  private applyNewFullName() {
    return this.pluginRestApi.put(
      `/config/server/serviceuser~serviceusers/${this.serviceUser?._account_id}/name`,
      {name: this.fullName}
    );
  }

  private applyNewEmail() {
    if (!this.isNewValidEmail(this.email)) {
      return;
    }
    return this.pluginRestApi.put(
      `/config/server/serviceuser~serviceusers/${this.serviceUser?._account_id}/email`,
      {email: this.email}
    );
  }

  private applyNewOwner() {
    if (!this.isNewOwner()) {
      return;
    }
    if (this.owner === '') {
      return this.pluginRestApi.delete(
        `/config/server/serviceuser~serviceusers/${this.serviceUser?._account_id}/owner`
      );
    }
    return this.pluginRestApi.put(
      `/config/server/serviceuser~serviceusers/${this.serviceUser?._account_id}/owner`,
      {group: this.owner}
    );
  }

  private handleSavePreferences() {
    const promises = [];
    this.changingPrefs = true;

    if (this.fullName !== this.serviceUser.name) {
      promises.push(this.applyNewFullName());
    }

    if (this.email !== this.serviceUser.email) {
      promises.push(this.applyNewEmail());
    }

    if (this.owner !== this.serviceUser.owner?.name) {
      promises.push(this.applyNewOwner());
    }

    Promise.all(promises)
      .then(() => {
        this.prefsChanged = false;
        this.ownerChangeWarning = '';
        this.loadServiceUser();
      })
      .catch(error => {
        this.dispatchEvent(
          new CustomEvent('show-error', {
            detail: {message: error},
            composed: true,
            bubbles: true,
          })
        );
      })
      .finally(() => {
        this.changingPrefs = false;
      });
  }
}
