/**
 * @license
 * Copyright 2022 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */

import {LitElement, html, css, PropertyValues} from 'lit';
import {customElement, property} from 'lit/decorators';
import {ChangeListSection} from '../gr-change-list/gr-change-list';
import {
  CLOSED,
  YOUR_TURN,
  GerritNav,
} from '../../core/gr-navigation/gr-navigation';
import {KnownExperimentId} from '../../../services/flags/flags';
import {getAppContext} from '../../../services/app-context';
import {ChangeInfo, ServerInfo, AccountInfo} from '../../../api/rest-api';
import {changeListStyles} from '../../../styles/gr-change-list-styles';
import {fontStyles} from '../../../styles/gr-font-styles';
import {sharedStyles} from '../../../styles/shared-styles';
import {Metadata} from '../../../utils/change-metadata-util';
import {WAITING} from '../../../constants/constants';
import {ifDefined} from 'lit/directives/if-defined';
import {provide} from '../../../models/dependency';
import {
  bulkActionsModelToken,
  BulkActionsModel,
} from '../../../models/bulk-actions/bulk-actions-model';

const NUMBER_FIXED_COLUMNS = 3;
const LABEL_PREFIX_INVALID_PROLOG = 'Invalid-Prolog-Rules-Label-Name--';
const MAX_SHORTCUT_CHARS = 5;
const INVALID_TOKENS = ['limit:', 'age:', '-age:'];

export function computeLabelShortcut(labelName: string) {
  if (labelName.startsWith(LABEL_PREFIX_INVALID_PROLOG)) {
    labelName = labelName.slice(LABEL_PREFIX_INVALID_PROLOG.length);
  }
  // Compute label shortcut by splitting token by - and capitalizing first
  // letter of each token.
  return labelName
    .split('-')
    .reduce((previousValue, currentValue) => {
      if (!currentValue) {
        return previousValue;
      }
      return previousValue + currentValue[0].toUpperCase();
    }, '')
    .slice(0, MAX_SHORTCUT_CHARS);
}

@customElement('gr-change-list-section')
export class GrChangeListSection extends LitElement {
  @property({type: Array})
  visibleChangeTableColumns?: string[];

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

  @property({type: Boolean})
  showNumber?: boolean; // No default value to prevent flickering.

  @property({type: Number})
  selectedIndex?: number; // The relative index of the change that is selected

  @property({type: Array})
  labelNames: string[] = [];

  @property({type: Array})
  dynamicHeaderEndpoints?: string[];

  @property({type: Object})
  changeSection!: ChangeListSection;

  @property({type: Object})
  config?: ServerInfo;

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

  /**
   * The logged-in user's account, or an empty object if no user is logged
   * in.
   */
  @property({type: Object})
  account: AccountInfo | undefined = undefined;

  private readonly flagsService = getAppContext().flagsService;

  bulkActionsModel: BulkActionsModel = new BulkActionsModel(
    getAppContext().restApiService
  );

  static override get styles() {
    return [
      changeListStyles,
      fontStyles,
      sharedStyles,
      css`
        :host {
          display: contents;
        }
        .section-count-label {
          color: var(--deemphasized-text-color);
          font-family: var(--font-family);
          font-size: var(--font-size-small);
          font-weight: var(--font-weight-normal);
          line-height: var(--line-height-small);
        }
      `,
    ];
  }

  constructor() {
    super();
    provide(this, bulkActionsModelToken, () => this.bulkActionsModel);
  }

  override willUpdate(changedProperties: PropertyValues) {
    if (changedProperties.has('changeSection')) {
      // In case the list of changes is updated due to auto reloading, we want
      // to ensure the model removes any stale change that is not a part of the
      // new section changes.
      this.bulkActionsModel.sync(this.changeSection.results);
    }
  }

  override render() {
    const columns = this.computeColumns();
    const colSpan = this.computeColspan(columns);
    return html`
      ${this.renderSectionHeader(colSpan)}
      <tbody class="groupContent">
        ${this.isEmpty()
          ? this.renderNoChangesRow(colSpan)
          : this.renderColumnHeaders(columns)}
        ${this.changeSection.results.map((change, index) =>
          this.renderChangeRow(change, index, columns)
        )}
      </tbody>
    `;
  }

  private renderNoChangesRow(colSpan: number) {
    return html`
      <tr class="noChanges">
        <td class="leftPadding" aria-hidden="true"></td>
        <td
          class="star"
          ?aria-hidden=${!this.showStar}
          ?hidden=${!this.showStar}
        ></td>
        <td class="cell" colspan="${colSpan}">
          ${this.changeSection!.emptyStateSlotName
            ? html`<slot
                name="${this.changeSection!.emptyStateSlotName}"
              ></slot>`
            : 'No changes'}
        </td>
      </tr>
    `;
  }

  private renderSectionHeader(colSpan: number) {
    if (
      this.changeSection.name === undefined ||
      this.changeSection.countLabel === undefined ||
      this.changeSection.query === undefined
    )
      return;

    return html`
      <tbody>
        <tr class="groupHeader">
          <td aria-hidden="true" class="leftPadding"></td>
          ${this.renderSelectionHeader()}
          <td aria-hidden="true" class="star" ?hidden=${!this.showStar}></td>
          <td class="cell" colspan="${colSpan}">
            <h2 class="heading-3">
              <a
                href="${this.sectionHref(this.changeSection!.query)}"
                class="section-title"
              >
                <span class="section-name">${this.changeSection!.name}</span>
                <span class="section-count-label"
                  >${this.changeSection.countLabel}</span
                >
              </a>
            </h2>
          </td>
        </tr>
      </tbody>
    `;
  }

  private renderColumnHeaders(columns: string[]) {
    return html`
      <tr class="groupTitle">
        <td class="leftPadding" aria-hidden="true"></td>
        ${this.renderSelectionHeader()}
        <td
          class="star"
          aria-label="Star status column"
          ?hidden=${!this.showStar}
        ></td>
        <td class="number" ?hidden=${!this.showNumber}>#</td>
        ${columns.map(item => this.renderHeaderCell(item))}
        ${this.labelNames?.map(labelName => this.renderLabelHeader(labelName))}
        ${this.dynamicHeaderEndpoints?.map(pluginHeader =>
          this.renderEndpointHeader(pluginHeader)
        )}
      </tr>
    `;
  }

  private renderSelectionHeader() {
    if (!this.flagsService.isEnabled(KnownExperimentId.BULK_ACTIONS)) return;
    return html`<td aria-hidden="true" class="selection"></td>`;
  }

  private renderHeaderCell(item: string) {
    return html`<td class="${item.toLowerCase()}">${item}</td>`;
  }

  private renderLabelHeader(labelName: string) {
    return html`
      <td class="label" title="${labelName}">
        ${computeLabelShortcut(labelName)}
      </td>
    `;
  }

  private renderEndpointHeader(pluginHeader: string) {
    return html`
      <td class="endpoint">
        <gr-endpoint-decorator .name="${pluginHeader}"></gr-endpoint-decorator>
      </td>
    `;
  }

  private renderChangeRow(
    change: ChangeInfo,
    index: number,
    columns: string[]
  ) {
    const ariaLabel = this.computeAriaLabel(change);
    const selected = this.computeItemSelected(index);
    const tabindex = this.computeTabIndex(index);
    return html`
      <gr-change-list-item
        .account=${this.account}
        ?selected=${selected}
        .change=${change}
        .config=${this.config}
        .sectionName=${this.changeSection!.name}
        .visibleChangeTableColumns=${columns}
        .showNumber=${this.showNumber}
        ?showStar=${this.showStar}
        tabindex=${ifDefined(tabindex)}
        .labelNames=${this.labelNames}
        aria-label="${ariaLabel}"
      ></gr-change-list-item>
    `;
  }

  /**
   * This methods allows us to customize the columns per section.
   * Private but used in test
   *
   */
  computeColumns() {
    const section = this.changeSection;
    if (!section || !this.visibleChangeTableColumns) return [];
    const cols = [...this.visibleChangeTableColumns];
    const updatedIndex = cols.indexOf(Metadata.UPDATED);
    if (section.name === YOUR_TURN.name && updatedIndex !== -1) {
      cols[updatedIndex] = WAITING;
    }
    if (section.name === CLOSED.name && updatedIndex !== -1) {
      cols[updatedIndex] = Metadata.SUBMITTED;
    }
    return cols;
  }

  // private but used in test
  computeItemSelected(index: number) {
    return index === this.selectedIndex;
  }

  private computeTabIndex(index: number) {
    if (this.isCursorMoving) return 0;
    return this.computeItemSelected(index) ? 0 : undefined;
  }

  // private but used in test
  computeColspan(cols: string[]) {
    if (!cols || !this.labelNames) return 1;
    return cols.length + this.labelNames.length + NUMBER_FIXED_COLUMNS;
  }

  // private but used in test
  processQuery(query: string) {
    let tokens = query.split(' ');
    tokens = tokens.filter(
      token =>
        !INVALID_TOKENS.some(invalidToken => token.startsWith(invalidToken))
    );
    return tokens.join(' ');
  }

  private sectionHref(query?: string) {
    if (!query) return;
    return GerritNav.getUrlForSearchQuery(this.processQuery(query));
  }

  // private but used in test
  isEmpty() {
    return !this.changeSection.results?.length;
  }

  private computeAriaLabel(change?: ChangeInfo) {
    const sectionName = this.changeSection.name;
    if (!change) return '';
    return change.subject + (sectionName ? `, section: ${sectionName}` : '');
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-change-list-section': GrChangeListSection;
  }
}
