/**
 * @license
 * Copyright 2015 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import '../../shared/gr-autocomplete/gr-autocomplete';
import '../../shared/gr-icon/gr-icon';
import {ServerInfo} from '../../../types/common';
import {
  AutocompleteCommitEvent,
  AutocompleteQuery,
  AutocompleteSuggestion,
  GrAutocomplete,
} from '../../shared/gr-autocomplete/gr-autocomplete';
import {MergeabilityComputationBehavior} from '../../../constants/constants';
import {sharedStyles} from '../../../styles/shared-styles';
import {LitElement, PropertyValues, html, css} from 'lit';
import {
  customElement,
  property,
  state,
  query as queryDec,
} from 'lit/decorators.js';
import {Shortcut, ShortcutController} from '../../lit/shortcut-controller';
import {assertIsDefined} from '../../../utils/common-util';
import {configModelToken} from '../../../models/config/config-model';
import {resolve} from '../../../models/dependency';
import {subscribe} from '../../lit/subscription-controller';
import {ValueChangedEvent} from '../../../types/events';
import {fireNoBubbleNoCompose} from '../../../utils/event-util';

// Possible static search options for auto complete, without negations.
const SEARCH_OPERATORS: ReadonlyArray<string> = [
  'added:',
  'after:',
  'age:',
  'age:1week', // Give an example age
  'attention:',
  'author:',
  'before:',
  'branch:',
  'bug:',
  'cc:',
  'cc:self',
  'change:',
  'cherrypickof:',
  'comment:',
  'commentby:',
  'commit:',
  'committer:',
  'deleted:',
  'delta:',
  'dir:',
  'directory:',
  'ext:',
  'extension:',
  'file:',
  'footer:',
  'from:',
  'has:',
  'has:attention',
  'has:draft',
  'has:edit',
  'has:star',
  'has:unresolved',
  'hashtag:',
  'inhashtag:',
  'intopic:',
  'is:',
  'is:abandoned',
  'is:attention',
  'is:cherrypick',
  'is:closed',
  'is:merge',
  'is:merged',
  'is:open',
  'is:owner',
  'is:private',
  'is:pure-revert',
  'is:reviewed',
  'is:reviewer',
  'is:starred',
  'is:submittable',
  'is:watched',
  'is:wip',
  'label:',
  'mergedafter:',
  'mergedbefore:',
  'message:',
  'onlyexts:',
  'onlyextensions:',
  'owner:',
  'ownerin:',
  'parentof:',
  'parentproject:',
  'project:',
  'projects:',
  'query:',
  'repo:',
  'ref:',
  'reviewedby:',
  'reviewer:',
  'reviewer:self',
  'reviewerin:',
  'rule:',
  'size:',
  'star:',
  'status:',
  'status:abandoned',
  'status:closed',
  'status:merged',
  'status:open',
  'status:reviewed',
  'submissionid:',
  'topic:',
  'tr:',
];

// All of the ops, with corresponding negations.
const SEARCH_OPERATORS_WITH_NEGATIONS_SET: ReadonlySet<string> = new Set(
  SEARCH_OPERATORS.concat(SEARCH_OPERATORS.map(op => `-${op}`))
);

const MAX_AUTOCOMPLETE_RESULTS = 10;

const TOKENIZE_REGEX = /(?:[^\s"]+|"[^"]*")+\s*/g;

export type SuggestionProvider = (
  predicate: string,
  expression: string
) => Promise<AutocompleteSuggestion[]>;

export interface SearchBarHandleSearchDetail {
  inputVal: string;
}

@customElement('gr-search-bar')
export class GrSearchBar extends LitElement {
  /**
   * Fired when a search is committed
   *
   * @event handle-search
   */

  @queryDec('#searchInput') protected searchInput?: GrAutocomplete;

  @property({type: String})
  value = '';

  @property({type: Object})
  projectSuggestions: SuggestionProvider = () => Promise.resolve([]);

  @property({type: Object})
  groupSuggestions: SuggestionProvider = () => Promise.resolve([]);

  @property({type: Object})
  accountSuggestions: SuggestionProvider = () => Promise.resolve([]);

  @state()
  serverConfig?: ServerInfo;

  @state()
  mergeabilityComputationBehavior?: MergeabilityComputationBehavior;

  @property({type: String})
  label = '';

  // private but used in test
  @state() inputVal = '';

  // private but used in test
  @state() docsBaseUrl: string | null = null;

  @state() private query: AutocompleteQuery;

  @state() private threshold = 1;

  private readonly shortcuts = new ShortcutController(this);

  private readonly getConfigModel = resolve(this, configModelToken);

  constructor() {
    super();
    this.query = (input: string) => this.getSearchSuggestions(input);
    this.shortcuts.addAbstract(Shortcut.SEARCH, () => this.handleSearch());
    subscribe(
      this,
      () => this.getConfigModel().mergeabilityComputationBehavior$,
      mergeabilityComputationBehavior => {
        this.mergeabilityComputationBehavior = mergeabilityComputationBehavior;
      }
    );
    subscribe(
      this,
      () => this.getConfigModel().docsBaseUrl$,
      docsBaseUrl => (this.docsBaseUrl = docsBaseUrl)
    );
  }

  static override get styles() {
    return [
      sharedStyles,
      css`
        gr-icon.searchIcon {
          margin: 0 var(--spacing-xs);
        }
        form {
          display: flex;
        }
        gr-autocomplete {
          background-color: var(--view-background-color);
          border-radius: var(--border-radius);
          flex: 1;
          outline: none;
        }
      `,
    ];
  }

  override render() {
    return html`
      <form>
        <gr-autocomplete
          id="searchInput"
          .label=${this.label}
          .text=${this.inputVal}
          .query=${this.query}
          allow-non-suggested-values
          multi
          .threshold=${this.threshold}
          tab-complete
          .verticalOffset=${30}
          @commit=${(e: AutocompleteCommitEvent) => {
            this.handleInputCommit(e);
          }}
          @text-changed=${(e: ValueChangedEvent) => {
            this.handleSearchTextChanged(e);
          }}
        >
          <gr-icon icon="search" class="searchIcon" slot="prefix"></gr-icon>
          <a
            class="help"
            slot="suffix"
            href=${this.computeHelpDocLink()}
            target="_blank"
            tabindex="-1"
          >
            <gr-icon icon="help" title="read documentation"></gr-icon>
          </a>
        </gr-autocomplete>
      </form>
    `;
  }

  override willUpdate(changedProperties: PropertyValues) {
    if (changedProperties.has('value')) {
      this.valueChanged();
    }
  }

  private valueChanged() {
    this.inputVal = this.value;
  }

  private searchOperators() {
    const set = new Set(SEARCH_OPERATORS_WITH_NEGATIONS_SET);
    if (
      this.mergeabilityComputationBehavior ===
        MergeabilityComputationBehavior.API_REF_UPDATED_AND_CHANGE_REINDEX ||
      this.mergeabilityComputationBehavior ===
        MergeabilityComputationBehavior.REF_UPDATED_AND_CHANGE_REINDEX
    ) {
      set.add('is:mergeable');
      set.add('-is:mergeable');
    }
    return set;
  }

  // private but used in test
  computeHelpDocLink() {
    // fallback to gerrit's official doc
    let baseUrl =
      this.docsBaseUrl ||
      'https://gerrit-review.googlesource.com/Documentation/';
    if (baseUrl.endsWith('/')) {
      baseUrl = baseUrl.substring(0, baseUrl.length - 1);
    }
    return `${baseUrl}/user-search.html`;
  }

  private handleInputCommit(e: AutocompleteCommitEvent) {
    this.preventDefaultAndNavigateToInputVal(e);
  }

  /**
   * This function is called in a few different cases:
   * - e.target is the search button
   * - e.target is the gr-autocomplete widget (#searchInput)
   * - e.target is the input element wrapped within #searchInput
   */
  private preventDefaultAndNavigateToInputVal(e: AutocompleteCommitEvent) {
    e.preventDefault();
    if (!this.inputVal) return;
    const trimmedInput = this.inputVal.trim();
    if (trimmedInput) {
      const predefinedOpOnlyQuery = [...this.searchOperators()].some(
        op => op.endsWith(':') && op === trimmedInput
      );
      if (predefinedOpOnlyQuery) {
        return;
      }
      const detail: SearchBarHandleSearchDetail = {
        inputVal: this.inputVal,
      };
      fireNoBubbleNoCompose(this, 'handle-search', detail);
    }
  }

  /**
   * Determine what array of possible suggestions should be provided
   * to getSearchSuggestions.
   *
   * @param input - The full search term, in lowercase.
   * @return This returns a promise that resolves to an array of
   * suggestion objects.
   */
  private fetchSuggestions(input: string): Promise<AutocompleteSuggestion[]> {
    // Split the input on colon to get a two part predicate/expression.
    const splitInput = input.split(':');
    const predicate = splitInput[0];
    const expression = splitInput[1] || '';
    // Switch on the predicate to determine what to autocomplete.
    switch (predicate) {
      case 'ownerin':
      case 'reviewerin':
        // Fetch groups.
        return this.groupSuggestions(predicate, expression);

      case 'parentproject':
      case 'project':
      case 'repo':
        // Fetch projects.
        return this.projectSuggestions(predicate, expression);

      case 'attention':
      case 'author':
      case 'cc':
      case 'commentby':
      case 'committer':
      case 'from':
      case 'owner':
      case 'reviewedby':
      case 'reviewer':
        // Fetch accounts.
        return this.accountSuggestions(predicate, expression);

      default:
        return Promise.resolve(
          [...this.searchOperators()]
            .filter(operator => operator.includes(input))
            .map(operator => {
              return {text: operator};
            })
        );
    }
  }

  /**
   * Get the sorted, pruned list of suggestions for the current search query.
   *
   * @param input - The complete search query.
   * @return This returns a promise that resolves to an array of
   * suggestions.
   *
   * private but used in test
   */
  getSearchSuggestions(input: string): Promise<AutocompleteSuggestion[]> {
    // Allow spaces within quoted terms.
    const tokens = input.match(TOKENIZE_REGEX);
    if (tokens === null) return Promise.resolve([]);
    const trimmedInput = tokens[tokens.length - 1].toLowerCase();

    return this.fetchSuggestions(trimmedInput).then(suggestions => {
      if (!suggestions || !suggestions.length) {
        return [];
      }
      return (
        suggestions
          // Prioritize results that start with the input.
          .sort((a, b) => {
            const aContains = a.text?.toLowerCase().indexOf(trimmedInput);
            const bContains = b.text?.toLowerCase().indexOf(trimmedInput);
            if (aContains === undefined && bContains === undefined) return 0;
            if (aContains === undefined && bContains !== undefined) return 1;
            if (aContains !== undefined && bContains === undefined) return -1;
            if (aContains === bContains) {
              return a.text!.localeCompare(b.text!);
            }
            if (aContains === -1) {
              return 1;
            }
            if (bContains === -1) {
              return -1;
            }
            return aContains! - bContains!;
          })
          // Return only the first {MAX_AUTOCOMPLETE_RESULTS} results.
          .slice(0, MAX_AUTOCOMPLETE_RESULTS - 1)
          // Map to an object to play nice with gr-autocomplete.
          .map(({text, label}) => {
            return {
              name: text,
              value: text,
              label,
            };
          })
      );
    });
  }

  private handleSearch() {
    assertIsDefined(this.searchInput, 'searchInput');
    this.searchInput.focus();
    this.searchInput.selectAll();
  }

  private handleSearchTextChanged(e: ValueChangedEvent) {
    this.inputVal = e.detail.value;
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-search-bar': GrSearchBar;
  }
}
