/**
 * @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';
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 {GrServiceUserHttpPassword} from './gr-serviceuser-http-password';

import './gr-serviceuser-ssh-panel';
import './gr-serviceuser-http-password';

const NOT_FOUND_MESSAGE = 'Not Found';

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

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

  @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-http-password 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;
      });
  }
}
