/**
 * @license
 * Copyright 2017 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import '../../shared/gr-autocomplete/gr-autocomplete';
import '../../shared/gr-button/gr-button';
import '../../shared/gr-copy-clipboard/gr-copy-clipboard';
import '../../shared/gr-select/gr-select';
import '../../shared/gr-textarea/gr-textarea';
import {
  AutocompleteSuggestion,
  AutocompleteQuery,
} from '../../shared/gr-autocomplete/gr-autocomplete';
import {GroupId, GroupInfo, GroupName} from '../../../types/common';
import {fire, firePageError, fireTitleChange} from '../../../utils/event-util';
import {getAppContext} from '../../../services/app-context';
import {ErrorCallback} from '../../../api/rest';
import {convertToString} from '../../../utils/string-util';
import {BindValueChangeEvent, ValueChangedEvent} from '../../../types/events';
import {fontStyles} from '../../../styles/gr-font-styles';
import {formStyles} from '../../../styles/gr-form-styles';
import {sharedStyles} from '../../../styles/shared-styles';
import {subpageStyles} from '../../../styles/gr-subpage-styles';
import {LitElement, PropertyValues, css, html} from 'lit';
import {customElement, property, state} from 'lit/decorators.js';
import {throwingErrorCallback} from '../../shared/gr-rest-api-interface/gr-rest-apis/gr-rest-api-helper';

const INTERNAL_GROUP_REGEX = /^[\da-f]{40}$/;

const OPTIONS = {
  submitFalse: {
    value: false,
    label: 'False',
  },
  submitTrue: {
    value: true,
    label: 'True',
  },
};

export interface GroupNameChangedDetail {
  name: GroupName;
  external: boolean;
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-group': GrGroup;
  }
  interface HTMLElementEventMap {
    'name-changed': CustomEvent<GroupNameChangedDetail>;
  }
}

@customElement('gr-group')
export class GrGroup extends LitElement {
  private readonly query: AutocompleteQuery;

  @property({type: String})
  groupId?: GroupId;

  @state() private originalOwnerName?: string;

  @state() private originalDescriptionName?: string;

  @state() private originalOptionsVisibleToAll?: boolean;

  @state() private submitTypes = Object.values(OPTIONS);

  // private but used in test
  @state() isAdmin = false;

  // private but used in test
  @state() groupOwner = false;

  // private but used in test
  @state() groupIsInternal = false;

  // private but used in test
  @state() loading = true;

  // private but used in test
  @state() groupConfig?: GroupInfo;

  // private but used in test
  @state() groupConfigOwner?: string;

  // private but used in test
  @state() originalName?: GroupName;

  private readonly restApiService = getAppContext().restApiService;

  constructor() {
    super();
    this.query = (input: string) => this.getGroupSuggestions(input);
  }

  override connectedCallback() {
    super.connectedCallback();
  }

  static override get styles() {
    return [
      fontStyles,
      formStyles,
      sharedStyles,
      subpageStyles,
      css`
        h3.edited:after {
          color: var(--deemphasized-text-color);
          content: ' *';
        }
      `,
    ];
  }

  override render() {
    return html`
      <div class="main gr-form-styles read-only">
        <div id="loading" class=${this.computeLoadingClass()}>Loading...</div>
        <div id="loadedContent" class=${this.computeLoadingClass()}>
          <h1 id="Title" class="heading-1">${this.originalName}</h1>
          <h2 id="configurations" class="heading-2">General</h2>
          <div id="form">
            <fieldset>
              ${this.renderGroupUUID()} ${this.renderGroupName()}
              ${this.renderGroupOwner()} ${this.renderGroupDescription()}
              ${this.renderGroupOptions()}
            </fieldset>
          </div>
        </div>
      </div>
    `;
  }

  private renderGroupUUID() {
    return html`
      <h3 id="groupUUID" class="heading-3">Group UUID</h3>
      <fieldset>
        <gr-copy-clipboard
          id="uuid"
          .text=${this.getGroupUUID()}
        ></gr-copy-clipboard>
      </fieldset>
    `;
  }

  private renderGroupName() {
    const groupNameEdited = this.originalName !== this.groupConfig?.name;
    return html`
      <h3
        id="groupName"
        class="heading-3 ${this.computeHeaderClass(groupNameEdited)}"
      >
        Group Name
      </h3>
      <fieldset>
        <span class="value">
          <gr-autocomplete
            id="groupNameInput"
            .text=${this.groupConfig?.name}
            ?disabled=${this.computeGroupDisabled()}
            @text-changed=${this.handleNameTextChanged}
          ></gr-autocomplete>
        </span>
        <span class="value">
          <gr-button
            id="inputUpdateNameBtn"
            ?disabled=${!groupNameEdited}
            @click=${this.handleSaveName}
          >
            Rename Group</gr-button
          >
        </span>
      </fieldset>
    `;
  }

  private renderGroupOwner() {
    const groupOwnerNameEdited =
      this.originalOwnerName !== this.groupConfig?.owner;
    return html`
      <h3
        id="groupOwner"
        class="heading-3 ${this.computeHeaderClass(groupOwnerNameEdited)}"
      >
        Owners
      </h3>
      <fieldset>
        <span class="value">
          <gr-autocomplete
            id="groupOwnerInput"
            .text=${this.groupConfig?.owner}
            .value=${this.groupConfigOwner}
            .query=${this.query}
            ?disabled=${this.computeGroupDisabled()}
            @text-changed=${this.handleOwnerTextChanged}
            @value-changed=${this.handleOwnerValueChanged}
          >
          </gr-autocomplete>
        </span>
        <span class="value">
          <gr-button
            id="inputUpdateOwnerBtn"
            ?disabled=${!groupOwnerNameEdited}
            @click=${this.handleSaveOwner}
          >
            Change Owners</gr-button
          >
        </span>
      </fieldset>
    `;
  }

  private renderGroupDescription() {
    const groupDescriptionEdited =
      this.originalDescriptionName !== this.groupConfig?.description;
    return html`
      <h3 class="heading-3 ${this.computeHeaderClass(groupDescriptionEdited)}">
        Description
      </h3>
      <fieldset>
        <div>
          <gr-textarea
            class="description"
            autocomplete="on"
            rows="4"
            monospace
            ?disabled=${this.computeGroupDisabled()}
            .text=${this.groupConfig?.description ?? ''}
            @text-changed=${this.handleDescriptionTextChanged}
          ></gr-textarea>
        </div>
        <span class="value">
          <gr-button
            ?disabled=${!groupDescriptionEdited}
            @click=${this.handleSaveDescription}
          >
            Save Description
          </gr-button>
        </span>
      </fieldset>
    `;
  }

  private renderGroupOptions() {
    // We make sure the value is a boolean
    // this is done so undefined is converted to false.
    const groupOptionsEdited =
      Boolean(this.originalOptionsVisibleToAll) !==
      Boolean(this.groupConfig?.options?.visible_to_all);

    // We have to convert boolean to string in order
    // for the selection to work correctly.
    // We also convert undefined to false using boolean.
    return html`
      <h3
        id="options"
        class="heading-3 ${this.computeHeaderClass(groupOptionsEdited)}"
      >
        Group Options
      </h3>
      <fieldset>
        <section>
          <span class="title">
            Make group visible to all registered users
          </span>
          <span class="value">
            <gr-select
              id="visibleToAll"
              .bindValue=${convertToString(
                Boolean(this.groupConfig?.options?.visible_to_all)
              )}
              @bind-value-changed=${this.handleOptionsBindValueChanged}
            >
              <select ?disabled=${this.computeGroupDisabled()}>
                ${this.submitTypes.map(
                  item => html`
                    <option value=${item.value}>${item.label}</option>
                  `
                )}
              </select>
            </gr-select>
          </span>
        </section>
        <span class="value">
          <gr-button
            ?disabled=${!groupOptionsEdited}
            @click=${this.handleSaveOptions}
          >
            Save Group Options
          </gr-button>
        </span>
      </fieldset>
    `;
  }

  override willUpdate(changedProperties: PropertyValues) {
    if (changedProperties.has('groupId')) {
      this.loadGroup();
    }
  }

  // private but used in test
  async loadGroup() {
    if (!this.groupId) return;

    const promises: Promise<unknown>[] = [];

    const errFn: ErrorCallback = response => {
      firePageError(response);
    };

    const config = await this.restApiService.getGroupConfig(
      this.groupId,
      errFn
    );
    if (!config || !config.name) return;

    if (config.description === undefined) {
      config.description = '';
    }

    this.originalName = config.name;
    this.originalOwnerName = config.owner;
    this.originalDescriptionName = config.description;
    this.groupIsInternal = !!config.id.match(INTERNAL_GROUP_REGEX);

    promises.push(
      this.restApiService.getIsAdmin().then(isAdmin => {
        this.isAdmin = !!isAdmin;
      })
    );

    promises.push(
      this.restApiService.getIsGroupOwner(config.name).then(isOwner => {
        this.groupOwner = !!isOwner;
      })
    );

    this.groupConfig = config;
    this.originalOptionsVisibleToAll = config?.options?.visible_to_all;

    fireTitleChange(config.name);

    await Promise.all(promises);
    this.loading = false;
  }

  // private but used in test
  computeLoadingClass() {
    return this.loading ? 'loading' : '';
  }

  // private but used in test
  async handleSaveName() {
    const groupConfig = this.groupConfig;
    if (!this.groupId || !groupConfig || !groupConfig.name) {
      return Promise.reject(new Error('invalid groupId or config name'));
    }
    const groupName = groupConfig.name;
    const config = await this.restApiService.saveGroupName(
      this.groupId,
      groupName
    );
    if (config.status === 200) {
      this.originalName = groupName;
      const detail: GroupNameChangedDetail = {
        name: groupName,
        external: !this.groupIsInternal,
      };
      fire(this, 'name-changed', detail);
      this.requestUpdate();
    }

    return;
  }

  // private but used in test
  async handleSaveOwner() {
    if (!this.groupId || !this.groupConfig) return;
    let owner = this.groupConfig.owner;
    if (this.groupConfigOwner) {
      owner = decodeURIComponent(this.groupConfigOwner);
    }
    if (!owner) return;
    await this.restApiService.saveGroupOwner(this.groupId, owner);
    this.originalOwnerName = this.groupConfig?.owner;
    this.groupConfigOwner = undefined;
  }

  // private but used in test
  async handleSaveDescription() {
    if (
      !this.groupId ||
      !this.groupConfig ||
      this.groupConfig.description === undefined
    )
      return;
    await this.restApiService.saveGroupDescription(
      this.groupId,
      this.groupConfig.description
    );
    this.originalDescriptionName = this.groupConfig.description;
  }

  // private but used in test
  async handleSaveOptions() {
    if (!this.groupId || !this.groupConfig || !this.groupConfig.options) return;
    const visible = this.groupConfig.options.visible_to_all;
    const options = {visible_to_all: visible};
    await this.restApiService.saveGroupOptions(this.groupId, options);
    this.originalOptionsVisibleToAll = visible;
  }

  private computeHeaderClass(configChanged: boolean) {
    return configChanged ? 'edited' : '';
  }

  private getGroupSuggestions(input: string) {
    return this.restApiService
      .getSuggestedGroups(
        input,
        /* project=*/ undefined,
        /* n=*/ undefined,
        throwingErrorCallback
      )
      .then(response => {
        const groups: AutocompleteSuggestion[] = [];
        for (const [name, group] of Object.entries(response ?? {})) {
          groups.push({name, value: decodeURIComponent(group.id)});
        }
        return groups;
      });
  }

  // private but used in test
  computeGroupDisabled() {
    return !(this.groupIsInternal && (this.isAdmin || this.groupOwner));
  }

  private getGroupUUID() {
    const id = this.groupConfig?.id;
    if (!id) return;
    return id.match(INTERNAL_GROUP_REGEX) ? id : decodeURIComponent(id);
  }

  private handleNameTextChanged(e: ValueChangedEvent) {
    if (!this.groupConfig || this.loading) return;
    this.groupConfig.name = e.detail.value as GroupName;
    this.requestUpdate();
  }

  private handleOwnerTextChanged(e: ValueChangedEvent) {
    if (!this.groupConfig || this.loading) return;
    this.groupConfig.owner = e.detail.value;
    this.requestUpdate();
  }

  private handleOwnerValueChanged(e: ValueChangedEvent) {
    if (this.loading) return;
    this.groupConfigOwner = e.detail.value;
    this.requestUpdate();
  }

  private handleDescriptionTextChanged(e: ValueChangedEvent) {
    if (!this.groupConfig || this.loading) return;
    this.groupConfig.description = e.detail.value;
    this.requestUpdate();
  }

  private handleOptionsBindValueChanged(e: BindValueChangeEvent) {
    if (!this.groupConfig || this.loading) return;

    // Because the value for e.detail.value is a string
    // we convert the value to a boolean.
    const value = e.detail.value === 'true' ? true : false;
    this.groupConfig.options!.visible_to_all = value;
    this.requestUpdate();
  }
}
