/**
 * @license
 * Copyright 2017 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import '@polymer/iron-input/iron-input';
import '../../shared/gr-button/gr-button';
import '../../shared/gr-icon/gr-icon';
import '../gr-permission/gr-permission';
import {
  AccessPermissions,
  PermissionArray,
  PermissionArrayItem,
  toSortedPermissionsArray,
} from '../../../utils/access-util';
import {
  EditablePermissionInfo,
  PermissionAccessSection,
  EditableRepoAccessGroups,
} from '../gr-repo-access/gr-repo-access-interfaces';
import {
  CapabilityInfoMap,
  GitRef,
  LabelNameToLabelTypeInfoMap,
  RepoName,
} from '../../../types/common';
import {fire} from '../../../utils/event-util';
import {IronInputElement} from '@polymer/iron-input/iron-input';
import {fontStyles} from '../../../styles/gr-font-styles';
import {grFormStyles} from '../../../styles/gr-form-styles';
import {sharedStyles} from '../../../styles/shared-styles';
import {LitElement, PropertyValues, html, css} from 'lit';
import {customElement, property, query, state} from 'lit/decorators.js';
import {BindValueChangeEvent, ValueChangedEvent} from '../../../types/events';
import {assertIsDefined, queryAndAssert} from '../../../utils/common-util';
import {repeat} from 'lit/directives/repeat.js';

const GLOBAL_NAME = 'GLOBAL_CAPABILITIES';

// The name that gets automatically input when a new reference is added.
const NEW_NAME = 'refs/heads/*';
const REFS_NAME = 'refs/';

@customElement('gr-access-section')
export class GrAccessSection extends LitElement {
  @query('#permissionSelect') private permissionSelect?: HTMLSelectElement;

  @property({type: String})
  repo?: RepoName;

  @property({type: Object})
  capabilities?: CapabilityInfoMap;

  @property({type: Object})
  section?: PermissionAccessSection;

  @property({type: Object})
  groups?: EditableRepoAccessGroups;

  @property({type: Object})
  labels?: LabelNameToLabelTypeInfoMap;

  @property({type: Boolean})
  editing = false;

  @property({type: Boolean})
  canUpload?: boolean;

  @property({type: Array})
  ownerOf?: GitRef[];

  // private but used in test
  @state() originalId?: GitRef;

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

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

  // private but used in test
  @state() permissions?: PermissionArray<EditablePermissionInfo>;

  constructor() {
    super();
    this.addEventListener('access-saved', () => this.handleAccessSaved());
  }

  static override get styles() {
    return [
      grFormStyles,
      fontStyles,
      sharedStyles,
      css`
        :host {
          display: block;
          margin-bottom: var(--spacing-l);
        }
        fieldset {
          border: 1px solid var(--border-color);
        }
        .name {
          align-items: center;
          display: flex;
        }
        .header,
        #deletedContainer {
          align-items: center;
          background: var(--table-header-background-color);
          border-bottom: 1px dotted var(--border-color);
          display: flex;
          justify-content: space-between;
          min-height: 3em;
          padding: 0 var(--spacing-m);
        }
        #deletedContainer {
          border-bottom: 0;
        }
        .sectionContent {
          padding: var(--spacing-m);
        }
        #editBtn,
        .editing #editBtn.global,
        #deletedContainer,
        .deleted #mainContainer,
        #addPermission,
        #deleteBtn,
        .editingRef .name,
        .editRefInput {
          display: none;
        }
        .editing #editBtn,
        .editingRef .editRefInput {
          display: flex;
        }
        .deleted #deletedContainer {
          display: flex;
        }
        .editing #addPermission,
        #mainContainer,
        .editing #deleteBtn {
          display: block;
        }
        .editing #deleteBtn,
        #undoRemoveBtn {
          padding-right: var(--spacing-m);
        }
      `,
    ];
  }

  override render() {
    if (!this.section) return;
    return html`
      <fieldset
        id="section"
        class="gr-form-styles ${this.computeSectionClass()}"
      >
        <div id="mainContainer">
          <div class="header">
            <div class="name">
              <h3 class="heading-3">${this.computeSectionName()}</h3>
              <gr-button
                id="editBtn"
                link
                class=${this.section?.id === GLOBAL_NAME ? 'global' : ''}
                @click=${this.editReference}
              >
                <gr-icon id="icon" icon="edit" filled small></gr-icon>
              </gr-button>
            </div>
            <iron-input
              class="editRefInput"
              .bindValue=${this.section?.id}
              @input=${this.handleValueChange}
              @bind-value-changed=${this.handleIdBindValueChanged}
            >
              <input
                class="editRefInput"
                type="text"
                @input=${this.handleValueChange}
              />
            </iron-input>
            <gr-button link id="deleteBtn" @click=${this.handleRemoveReference}
              >Remove</gr-button
            >
          </div>
          <!-- end header -->
          <div class="sectionContent">
            ${repeat(
              this.permissions ?? [],
              perm => perm.id,
              (permission, index) => this.renderPermission(permission, index)
            )}
            <div id="addPermission">
              Add permission:
              <select id="permissionSelect">
                ${this.computePermissions().map(item =>
                  this.renderPermissionOptions(item)
                )}
              </select>
              <gr-button link id="addBtn" @click=${this.handleAddPermission}
                >Add</gr-button
              >
            </div>
            <!-- end addPermission -->
          </div>
          <!-- end sectionContent -->
        </div>
        <!-- end mainContainer -->
        <div id="deletedContainer">
          <span>${this.computeSectionName()} was deleted</span>
          <gr-button link="" id="undoRemoveBtn" @click=${this._handleUndoRemove}
            >Undo</gr-button
          >
        </div>
        <!-- end deletedContainer -->
      </fieldset>
    `;
  }

  private renderPermission(
    permission: PermissionArrayItem<EditablePermissionInfo>,
    index: number
  ) {
    return html`
      <gr-permission
        .name=${this.computePermissionName(permission)}
        .permission=${permission}
        .labels=${this.labels}
        .section=${this.section?.id}
        .editing=${this.editing}
        .groups=${this.groups}
        .repo=${this.repo}
        @added-permission-removed=${() => {
          this.handleAddedPermissionRemoved(index);
        }}
        @permission-changed=${(
          e: ValueChangedEvent<PermissionArrayItem<EditablePermissionInfo>>
        ) => {
          this.handlePermissionChanged(e, index);
        }}
      >
      </gr-permission>
    `;
  }

  private renderPermissionOptions(item: {
    id: string;
    value: {name: string; id: string};
  }) {
    return html`<option value=${item.value.id}>${item.value.name}</option>`;
  }

  override willUpdate(changedProperties: PropertyValues) {
    if (changedProperties.has('section')) {
      this.updateSection();
    }
    if (changedProperties.has('editing')) {
      this.handleEditingChanged(changedProperties.get('editing') as boolean);
    }
  }

  // private but used in test
  updateSection() {
    this.permissions = toSortedPermissionsArray(
      this.section!.value.permissions
    );
    this.originalId = this.section!.id;
  }

  // private but used in test
  handleAccessSaved() {
    if (!this.section) return;
    // Set a new 'original' value to keep track of after the value has been
    // saved.
    this.updateSection();
  }

  // private but used in test
  handleValueChange() {
    if (!this.section) {
      return;
    }
    if (!this.section.value.added) {
      this.section.value.modified = this.section.id !== this.originalId;
      this.requestUpdate();
      // Allows overall access page to know a change has been made.
      // For a new section, this is not fired because new permissions and
      // rules have to be added in order to save, modifying the ref is not
      // enough.
      fire(this, 'access-modified', {});
    }
    this.section.value.updatedId = this.section.id;
    this.requestUpdate();
  }

  private handleEditingChanged(editingOld: boolean) {
    // Ignore when editing gets set initially.
    if (!editingOld) {
      return;
    }
    if (!this.section || !this.permissions) {
      return;
    }
    // Restore original values if no longer editing.
    if (!this.editing) {
      this.editingRef = false;
      this.deleted = false;
      delete this.section.value.deleted;
      // Restore section ref.
      this.section.id = this.originalId as GitRef;
      this.requestUpdate();
      fire(this, 'section-changed', {value: this.section});
      // Remove any unsaved but added permissions.
      this.permissions = this.permissions.filter(p => !p.value.added);
      for (const key of Object.keys(this.section.value.permissions)) {
        if (this.section.value.permissions[key].added) {
          delete this.section.value.permissions[key];
        }
      }
    }
  }

  // private but used in test
  computePermissions() {
    let allPermissions;
    const section = this.section;
    if (!section || !section.value) {
      return [];
    }
    if (section.id === GLOBAL_NAME) {
      allPermissions = toSortedPermissionsArray(this.capabilities);
    } else {
      const labelOptions = this.computeLabelOptions();
      allPermissions = labelOptions.concat(
        toSortedPermissionsArray(AccessPermissions)
      );
    }
    return allPermissions.filter(
      permission => !section.value.permissions[permission.id]
    );
  }

  private handleAddedPermissionRemoved(index: number) {
    if (!this.permissions) {
      return;
    }
    delete this.section?.value.permissions[this.permissions[index].id];
    this.permissions = this.permissions
      .slice(0, index)
      .concat(this.permissions.slice(index + 1, this.permissions.length));
  }

  computeLabelOptions() {
    const labelOptions = [];
    if (!this.labels) {
      return [];
    }
    for (const labelName of Object.keys(this.labels)) {
      labelOptions.push({
        id: 'label-' + labelName,
        value: {
          name: `Label ${labelName}`,
          id: 'label-' + labelName,
        },
      });
      labelOptions.push({
        id: 'labelAs-' + labelName,
        value: {
          name: `Label ${labelName} (On Behalf Of)`,
          id: 'labelAs-' + labelName,
        },
      });
      labelOptions.push({
        id: 'removeLabel-' + labelName,
        value: {
          name: `Remove Label ${labelName}`,
          id: 'removeLabel-' + labelName,
        },
      });
    }
    return labelOptions;
  }

  // private but used in test
  computePermissionName(
    permission: PermissionArrayItem<EditablePermissionInfo>
  ): string | undefined {
    if (this.section?.id === GLOBAL_NAME) {
      return this.capabilities?.[permission.id]?.name;
    } else if (AccessPermissions[permission.id]) {
      return AccessPermissions[permission.id]?.name;
    } else if (permission.value.label) {
      if (permission.id.startsWith('labelAs-')) {
        return `Label ${permission.value.label} (On Behalf Of)`;
      } else if (permission.id.startsWith('removeLabel-')) {
        return `Remove Label ${permission.value.label}`;
      } else {
        return `Label ${permission.value.label}`;
      }
    }
    return undefined;
  }

  // private but used in test
  computeSectionName() {
    let name = this.section?.id;
    // When a new section is created, it doesn't yet have a ref. Set into
    // edit mode so that the user can input one.
    if (!name) {
      this.editingRef = true;
      // Needed for the title value. This is the same default as GWT.
      name = NEW_NAME as GitRef;
      // Needed for the input field value.
      this.section!.id = name;
      fire(this, 'section-changed', {value: this.section!});
      this.requestUpdate();
    }
    if (name === GLOBAL_NAME) {
      return 'Global Capabilities';
    } else if (name.startsWith(REFS_NAME)) {
      return `Reference: ${name}`;
    }
    return name;
  }

  private handleRemoveReference() {
    if (!this.section) {
      return;
    }
    if (this.section.value.added) {
      fire(this, 'added-section-removed', {});
    }
    this.deleted = true;
    this.section.value.deleted = true;
    fire(this, 'access-modified', {});
  }

  _handleUndoRemove() {
    if (!this.section) {
      return;
    }
    this.deleted = false;
    delete this.section.value.deleted;
    this.requestUpdate();
  }

  editRefInput() {
    return queryAndAssert<IronInputElement>(this, 'iron-input.editRefInput');
  }

  editReference() {
    this.editingRef = true;
    this.editRefInput().focus();
  }

  private isEditEnabled() {
    return (
      this.canUpload ||
      (this.ownerOf && this.ownerOf.indexOf(this.section!.id) >= 0)
    );
  }

  // private but used in test
  computeSectionClass() {
    const classList = [];
    if (this.editing && this.section && this.isEditEnabled()) {
      classList.push('editing');
    }
    if (this.editingRef) {
      classList.push('editingRef');
    }
    if (this.deleted) {
      classList.push('deleted');
    }
    return classList.join(' ');
  }

  // private but used in test
  handleAddPermission() {
    assertIsDefined(this.permissionSelect, 'permissionSelect');
    const value = this.permissionSelect.value as GitRef;
    const permission: PermissionArrayItem<EditablePermissionInfo> = {
      id: value,
      value: {rules: {}, added: true},
    };

    // This is needed to update the 'label' property of the
    // 'label-<label-name>' permission.
    //
    // The value from the add permission dropdown will either be
    // label-<label-name> or labelAs-<labelName>.
    // But, the format of the API response is as such:
    // "permissions": {
    //  "label-Code-Review": {
    //    "label": "Code-Review",
    //    "rules": {...}
    //    }
    //  }
    // }
    // When we add a new item, we have to push the new permission in the same
    // format as the ones that have been returned by the API.
    if (value.startsWith('label') || value.startsWith('removeLabel')) {
      permission.value.label = value
        .replace('label-', '')
        .replace('labelAs-', '')
        .replace('removeLabel-', '');
    }
    // Add to the end of the array (used in dom-repeat) and also to the
    // section object that is two way bound with its parent element.
    this.permissions!.push(permission);
    this.section!.value.permissions[permission.id] = permission.value;
    this.requestUpdate();
    fire(this, 'section-changed', {value: this.section!});
  }

  private handleIdBindValueChanged = (e: BindValueChangeEvent) => {
    this.section!.id = e.detail.value as GitRef;
    this.requestUpdate();
    fire(this, 'section-changed', {value: this.section!});
  };

  private handlePermissionChanged = (
    e: ValueChangedEvent<PermissionArrayItem<EditablePermissionInfo>>,
    index: number
  ) => {
    this.permissions![index] = e.detail.value;
    this.requestUpdate();
  };
}

declare global {
  interface HTMLElementEventMap {
    /** Fired when the section has been modified or removed. */
    'access-modified': CustomEvent<{}>;
    /** Fired when a section that was previously added was removed. */
    'added-section-removed': CustomEvent<{}>;
    'section-changed': ValueChangedEvent<PermissionAccessSection>;
  }
  interface HTMLElementTagNameMap {
    'gr-access-section': GrAccessSection;
  }
}
