/**
 * @license
 * Copyright 2022 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import {css, html, LitElement, nothing} from 'lit';
import {customElement, query, state} from 'lit/decorators';
import {bulkActionsModelToken} from '../../../models/bulk-actions/bulk-actions-model';
import {resolve} from '../../../models/dependency';
import {ChangeInfo, Hashtag} from '../../../types/common';
import {subscribe} from '../../lit/subscription-controller';
import '../../shared/gr-button/gr-button';
import '../../shared/gr-autocomplete/gr-autocomplete';
import '@polymer/iron-dropdown/iron-dropdown';
import {IronDropdownElement} from '@polymer/iron-dropdown/iron-dropdown';
import {getAppContext} from '../../../services/app-context';
import {notUndefined} from '../../../types/types';
import {unique} from '../../../utils/common-util';
import {AutocompleteSuggestion} from '../../shared/gr-autocomplete/gr-autocomplete';
import {when} from 'lit/directives/when';
import {ValueChangedEvent} from '../../../types/events';
import {classMap} from 'lit/directives/class-map';
import {spinnerStyles} from '../../../styles/gr-spinner-styles';
import {ProgressStatus} from '../../../constants/constants';
import {allSettled} from '../../../utils/async-util';

@customElement('gr-change-list-hashtag-flow')
export class GrChangeListHashtagFlow extends LitElement {
  @state() private selectedChanges: ChangeInfo[] = [];

  @state() private hashtagToAdd: Hashtag = '' as Hashtag;

  @state() private existingHashtagSuggestions: Hashtag[] = [];

  @state() private loadingText?: string;

  @state() private errorText?: string;

  /** dropdown status is tracked here to lazy-load the inner DOM contents */
  @state() private isDropdownOpen = false;

  @state() private overallProgress: ProgressStatus = ProgressStatus.NOT_STARTED;

  @query('iron-dropdown') private dropdown?: IronDropdownElement;

  private selectedExistingHashtags: Set<Hashtag> = new Set();

  private getBulkActionsModel = resolve(this, bulkActionsModelToken);

  private restApiService = getAppContext().restApiService;

  static override get styles() {
    return [
      spinnerStyles,
      css`
        iron-dropdown {
          box-shadow: var(--elevation-level-2);
          width: 400px;
          background-color: var(--dialog-background-color);
          border-radius: 4px;
        }
        [slot='dropdown-content'] {
          padding: var(--spacing-xl) var(--spacing-l) var(--spacing-l);
        }
        gr-autocomplete {
          --border-color: var(--gray-800);
        }
        .footer {
          display: flex;
          justify-content: space-between;
          align-items: baseline;
        }
        .buttons {
          padding-top: var(--spacing-m);
          display: flex;
          justify-content: flex-end;
          gap: var(--spacing-m);
        }
        .chips {
          display: flex;
          flex-wrap: wrap;
          gap: 6px;
        }
        .chip {
          padding: var(--spacing-s) var(--spacing-xl);
          border-radius: 10px;
          width: fit-content;
          cursor: pointer;
        }
        .chip:not(.selected) {
          border: var(--spacing-xxs) solid var(--gray-300);
        }
        .chip.selected {
          color: var(--blue-800);
          background-color: var(--blue-50);
          margin: var(--spacing-xxs);
        }
        .loadingOrError {
          display: flex;
          gap: var(--spacing-s);
        }

        /* The basics of .loadingSpin are defined in spinnerStyles. */
        .loadingSpin {
          vertical-align: top;
          position: relative;
          top: 3px;
        }
      `,
    ];
  }

  constructor() {
    super();
    subscribe(
      this,
      () => this.getBulkActionsModel().selectedChanges$,
      selectedChanges => {
        this.selectedChanges = selectedChanges;
      }
    );
  }

  override render() {
    const isFlowDisabled = this.selectedChanges.length === 0;
    return html`
      <gr-button
        id="start-flow"
        flatten
        @click=${this.toggleDropdown}
        .disabled=${isFlowDisabled}
        >Hashtag</gr-button
      >
      <iron-dropdown
        .horizontalAlign=${'auto'}
        .verticalAlign=${'auto'}
        .verticalOffset=${24}
        @opened-changed=${(e: CustomEvent) =>
          (this.isDropdownOpen = e.detail.value)}
      >
        ${when(
          this.isDropdownOpen,
          () => html`
            <div slot="dropdown-content">
              ${when(
                this.selectedChanges.some(change => change.hashtags?.length),
                () => this.renderExistingHashtagsMode(),
                () => this.renderNoExistingHashtagsMode()
              )}
            </div>
          `
        )}
      </iron-dropdown>
    `;
  }

  private renderExistingHashtagsMode() {
    const hashtags = this.selectedChanges
      .flatMap(change => change.hashtags ?? [])
      .filter(notUndefined)
      .filter(unique);
    const removeDisabled =
      this.selectedExistingHashtags.size === 0 ||
      this.overallProgress === ProgressStatus.RUNNING;
    const applyToAllDisabled = this.selectedExistingHashtags.size !== 1;
    return html`
      <div class="chips">
        ${hashtags.map(name => this.renderExistingHashtagChip(name))}
      </div>
      <div class="footer">
        <div class="loadingOrError">${this.renderLoadingOrError()}</div>
        <div class="buttons">
          <gr-button
            id="apply-to-all-button"
            flatten
            ?disabled=${applyToAllDisabled}
            @click=${this.applyHashtagToAll}
            >Apply to all</gr-button
          >
          <gr-button
            id="remove-hashtags-button"
            flatten
            ?disabled=${removeDisabled}
            @click=${this.removeHashtags}
            >Remove</gr-button
          >
        </div>
      </div>
    `;
  }

  private renderExistingHashtagChip(name: Hashtag) {
    const chipClasses = {
      chip: true,
      selected: this.selectedExistingHashtags.has(name),
    };
    return html`
      <span
        role="button"
        aria-label=${name as string}
        class=${classMap(chipClasses)}
        @click=${() => this.toggleExistingHashtagSelected(name)}
      >
        ${name}
      </span>
    `;
  }

  private renderLoadingOrError() {
    if (this.overallProgress === ProgressStatus.RUNNING) {
      return html`
        <span class="loadingSpin"></span>
        <span class="loadingText">${this.loadingText}</span>
      `;
    } else if (this.errorText !== undefined) {
      return html`<div class="error">${this.errorText}</div>`;
    }
    return nothing;
  }

  private renderNoExistingHashtagsMode() {
    const isCreateNewHashtagDisabled =
      this.hashtagToAdd === '' ||
      this.existingHashtagSuggestions.includes(this.hashtagToAdd) ||
      this.overallProgress === ProgressStatus.RUNNING;
    const isApplyHashtagDisabled =
      this.hashtagToAdd === '' ||
      !this.existingHashtagSuggestions.includes(this.hashtagToAdd) ||
      this.overallProgress === ProgressStatus.RUNNING;
    return html`
      <!--
        The .query function needs to be bound to this because lit's autobind
        seems to work only for @event handlers.
        'this.getHashtagSuggestions.bind(this)' gets in trouble with our linter
        even though the bind is necessary here, so an anonymous function is used
        instead.
      -->
      <gr-autocomplete
        .text=${this.hashtagToAdd}
        .query=${(query: string) => this.getHashtagSuggestions(query)}
        show-blue-focus-border
        placeholder="Type hashtag name to create or filter hashtags"
        @text-changed=${(e: ValueChangedEvent<Hashtag>) =>
          (this.hashtagToAdd = e.detail.value)}
      ></gr-autocomplete>
      <div class="footer">
        <div class="loadingOrError">${this.renderLoadingOrError()}</div>
        <div class="buttons">
          <gr-button
            id="create-new-hashtag-button"
            flatten
            @click=${() => this.addHashtag('Creating hashtag...')}
            .disabled=${isCreateNewHashtagDisabled}
            >Create new hashtag</gr-button
          >
          <gr-button
            id="apply-hashtag-button"
            flatten
            @click=${() => this.addHashtag('Applying hashtag...')}
            .disabled=${isApplyHashtagDisabled}
            >Apply</gr-button
          >
        </div>
      </div>
    `;
  }

  private toggleDropdown() {
    if (this.isDropdownOpen) {
      this.closeDropdown();
    } else {
      this.reset();
      this.openDropdown();
    }
  }

  private reset() {
    this.hashtagToAdd = '' as Hashtag;
    this.selectedExistingHashtags = new Set();
    this.overallProgress = ProgressStatus.NOT_STARTED;
    this.errorText = undefined;
  }

  private closeDropdown() {
    this.isDropdownOpen = false;
    this.dropdown?.close();
  }

  private openDropdown() {
    this.isDropdownOpen = true;
    this.dropdown?.open();
  }

  private async getHashtagSuggestions(
    query: string
  ): Promise<AutocompleteSuggestion[]> {
    const suggestions = await this.restApiService.getChangesWithSimilarHashtag(
      query
    );
    this.existingHashtagSuggestions = (suggestions ?? [])
      .flatMap(change => change.hashtags ?? [])
      .filter(notUndefined)
      .filter(unique);
    return this.existingHashtagSuggestions.map(hashtag => {
      return {name: hashtag, value: hashtag};
    });
  }

  private removeHashtags() {
    this.loadingText = `Removing hashtag${
      this.selectedExistingHashtags.size > 1 ? 's' : ''
    }...`;
    this.trackPromises(
      this.selectedChanges
        .filter(
          change =>
            change.hashtags &&
            change.hashtags.some(hashtag =>
              this.selectedExistingHashtags.has(hashtag)
            )
        )
        .map(change =>
          this.restApiService.setChangeHashtag(change._number, {
            remove: Array.from(this.selectedExistingHashtags.values()),
          })
        )
    );
  }

  private applyHashtagToAll() {
    this.loadingText = 'Applying hashtag to all';
    this.trackPromises(
      this.selectedChanges.map(change =>
        this.restApiService.setChangeHashtag(change._number, {
          add: Array.from(this.selectedExistingHashtags.values()),
        })
      )
    );
  }

  private addHashtag(loadingText: string) {
    this.loadingText = loadingText;
    this.trackPromises(
      this.selectedChanges.map(change =>
        this.restApiService.setChangeHashtag(change._number, {
          add: [this.hashtagToAdd],
        })
      )
    );
  }

  private async trackPromises(promises: Promise<Hashtag[]>[]) {
    this.overallProgress = ProgressStatus.RUNNING;
    const results = await allSettled(promises);
    if (results.every(result => result.status === 'fulfilled')) {
      this.overallProgress = ProgressStatus.SUCCESSFUL;
      this.closeDropdown();
      // TODO: fire reload of dashboard
    } else {
      this.overallProgress = ProgressStatus.FAILED;
      // TODO: when some are rejected, show error and Cancel button
    }
  }

  private toggleExistingHashtagSelected(name: Hashtag) {
    if (this.selectedExistingHashtags.has(name)) {
      this.selectedExistingHashtags.delete(name);
    } else {
      this.selectedExistingHashtags.add(name);
    }
    this.requestUpdate();
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-change-list-hashtag-flow': GrChangeListHashtagFlow;
  }
}
