/**
 * @module modules/search-page-sk
 * @description <h2><code>search-page-sk</code></h2>
 *
 */
import { html } from 'lit-html';
import { define } from 'elements-sk/define';
import { jsonOrThrow } from 'common-sk/modules/jsonOrThrow';
import { deepCopy } from 'common-sk/modules/object';
import { stateReflector } from 'common-sk/modules/stateReflector';
import { ParamSet, fromParamSet, fromObject } from 'common-sk/modules/query';
import dialogPolyfill from 'dialog-polyfill';
import { HintableObject } from 'common-sk/modules/hintable';
import { ElementSk } from '../../../infra-sk/modules/ElementSk';
import { ChangelistControlsSkChangeEventDetail } from '../changelist-controls-sk/changelist-controls-sk';
import { SearchCriteria, SearchCriteriaToHintableObject, SearchCriteriaFromHintableObject } from '../search-controls-sk/search-controls-sk';
import { sendBeginTask, sendEndTask, sendFetchError } from '../common';
import { defaultCorpus } from '../settings';
import { SearchResponse, StatusResponse, ParamSetResponse, SearchResult, ChangelistSummaryResponse, TriageRequestData, Label } from '../rpc_types';

import 'elements-sk/checkbox-sk';
import 'elements-sk/styles/buttons';
import '../bulk-triage-sk';
import '../search-controls-sk';
import '../changelist-controls-sk';
import '../digest-details-sk';

// Used to include/exclude the corpus field from the various ParamSets being passed around.
const CORPUS_KEY = 'source_type';

/**
 * Counterpart to SearchRespose (declared in rpc_types.ts).
 *
 * Contains the query string arguments to the /json/v1/search RPC. Intended to be used with
 * common-sk's fromObject() function.
 *
 * This type cannot be generated from Go because there is no counterpart Go struct.
 *
 * TODO(lovisolo): Consider reworking the /json/v1/search RPC to take arguments via POST, so that
 *                 we're able to unmarshal the JSON arguments into a SearchRequest Go struct. That
 *                 struct can then be converted into TypeScript via go2ts and used here, instead of
 *                 the ad-hoc SearchRequest interface defined below.
 * TODO(lovisolo): Consider generating the SearchCriteria struct from the above Go struct so we can
 *                 use the same type across the whole stack.
 */
export interface SearchRequest {
  // Fields populated via the page's query string.
  blame?: string;
  crs?: string;
  issue?: string;
  use_sql?: boolean;

  // Fields populated via the changelist-controls-sk.
  master?: boolean; // Show all results if true, or exclude results from the master branch if false.
  patchsets?: number;

  // Fields populated via the search-controls-sk.
  query: string;
  rquery: string;
  pos: boolean;
  neg: boolean;
  unt: boolean;
  head: boolean;  // At head only.
  include: boolean;  // Include ignored.
  frgbamin: number;
  frgbamax: number;
  fref: boolean;
  sort: 'asc' | 'desc';
}

export class SearchPageSk extends ElementSk {
  private static _template = (el: SearchPageSk) => html`
    <div class="top-controls">
      <search-controls-sk .corpora=${el._corpora}
                          .searchCriteria=${el._searchCriteria}
                          .paramSet=${el._paramSet}
                          @search-controls-sk-change=${el._onSearchControlsChange}>
      </search-controls-sk>
      <div class="buttons">
        <button class="bulk-triage" @click=${() => el._bulkTriageDialog?.showModal()}>
          Bulk Triage
        </button>
        <button class="help" @click=${() => el._helpDialog?.showModal()}>
          Help
        </button>
      </div>
    </div>

    <!-- This is only visible when the summary property is not null. -->
    <changelist-controls-sk .ps_order=${el._patchset}
                            .include_master=${el._includeDigestsFromPrimary}
                            .summary=${el._changeListSummaryResponse}
                            @cl-control-change=${el._onChangelistControlsChange}>
    </changelist-controls-sk>

    <p class=summary>${SearchPageSk._summary(el)}</p>

    <div class="results">
      ${el._searchResponse?.digests?.map(
        (result, idx) =>
          SearchPageSk._resultTemplate(
            el, result!, /* selected= */ idx === el._selectedSearchResultIdx))}
    </div>

    <dialog class="bulk-triage">
      <bulk-triage-sk .currentPageDigests=${el._getCurrentPageDigestsTriageRequestData()}
                      .allDigests=${el._searchResponse?.bulk_triage_data || {}}
                      .crs=${el._crs || ''}
                      .changeListID=${el._changelistId || ''}
                      @bulk_triage_invoked=${() => el._bulkTriageDialog?.close()}
                      @bulk_triage_finished=${() => el._fetchSearchResults()}
                      @bulk_triage_cancelled=${() => el._bulkTriageDialog?.close()}>
      </bulk-triage-sk>
    </dialog>

    <dialog class="help">
      <h2>Keyboard shortcuts</h2>
      <dl>
        <dt>J</dt> <dd>Next digest</dd>
        <dt>K</dt> <dd>Previous digest</dd>
        <dt>W</dt> <dd>Zoom into current digest</dd>
        <dt>A</dt> <dd>Mark as positive</dd>
        <dt>S</dt> <dd>Mark as negative</dd>
        <dt>D</dt> <dd>Mark as untriaged</dd>
        <dt>?</dt> <dd>Show help dialog</dd>
      </dl>
      <div class="buttons">
        <button class="cancel action" @click=${() => el._helpDialog?.close()}>Close</button>
      </div>
    </dialog>`;

  private static _summary = (el: SearchPageSk) => {
    if (!el._searchResponse) {
      return ''; // No results have been loaded yet. It's OK not to show anything at this point.
    }

    if (el._searchResponse.size === 0) {
      return 'No results matched your search criteria.';
    }

    const first = el._searchResponse.offset + 1;
    const last = el._searchResponse.offset + el._searchResponse.digests!.length;
    const total = el._searchResponse.size;
    return `Showing results ${first} to ${last} (out of ${total}).`;
  }

  // Note: The "selected" class is added/removed via DOM manipulations outside of lit-html for
  // performance reasons when navigating search results via the "J" and "K" keyboard shortcuts.
  // This is because re-rendering the search page can be very slow when displaying a large number of
  // search results.
  private static _resultTemplate =
    (el: SearchPageSk, result: SearchResult, selected: boolean) => html`
      <digest-details-sk .commits=${el._searchResponse?.commits}
                         .details=${result}
                         .changeListID=${el._changelistId}
                         .crs=${el._crs}
                         @triage=${(e: CustomEvent<Label>) => el._onTriage(result, e.detail)}
                         class="${selected ? 'selected' : ''}">
      </digest-details-sk>
    `;

  // Reflected to/from the URL and modified by the search-controls-sk.
  private _searchCriteria: SearchCriteria = {
    corpus: defaultCorpus(),
    leftHandTraceFilter: {},
    rightHandTraceFilter: {},
    includePositiveDigests: false,
    includeNegativeDigests: false,
    includeUntriagedDigests: true,
    includeDigestsNotAtHead: false,
    includeIgnoredDigests: false,
    minRGBADelta: 0,
    maxRGBADelta: 255,
    mustHaveReferenceImage: false,
    sortOrder: 'descending'
  };

  // Fields reflected to/from the URL and modified by the changelist-controls-sk.
  private _includeDigestsFromPrimary: boolean | null = null;
  private _patchset: number | null = null;

  // Other fields reflected from the URL.
  private _blame: string | null = null;
  private _crs: string | null = null;
  private _changelistId: string | null = null;
  private _useSQL: boolean = false;

  // stateReflector update function.
  private _stateChanged: (() => void) | null = null;

  // Fields populated from JSON RPCs.
  private _corpora: string[] = [];
  private _paramSet: ParamSet = {};
  private _changeListSummaryResponse: ChangelistSummaryResponse | null = null;
  private _searchResponse: SearchResponse | null = null;

  private _searchResultsFetchController: AbortController | null = null;

  private _bulkTriageDialog: HTMLDialogElement | null = null;
  private _helpDialog: HTMLDialogElement | null = null;

  private _keyDownEventHandlerFn: ((event: KeyboardEvent) => void) | null = null;

  // Search result currently selected (e.g. via the J and K keyboard shortcuts). A negative value
  // represents an empty selection.
  private _selectedSearchResultIdx: number = -1;

  constructor() {
    super(SearchPageSk._template);

    this._stateChanged = stateReflector(
      /* getState */ () => {
        const state = SearchCriteriaToHintableObject(this._searchCriteria) as HintableObject;
        state.blame = this._blame || '';
        state.crs = this._crs || '';
        state.issue = this._changelistId || '';
        state.use_sql = this._useSQL || '';
        state.master = this._includeDigestsFromPrimary || '';
        state.patchsets = this._patchset || '';
        return state;
      },
      /* setState */ (newState) => {
        if (!this._connected) {
          return;
        }
        this._searchCriteria = SearchCriteriaFromHintableObject(newState);
        this._blame = (newState.blame as string) || null;
        this._crs = (newState.crs as string) || null;
        this._changelistId = (newState.issue as string) || null;
        this._useSQL = (newState.use_sql as boolean) || false;
        this._includeDigestsFromPrimary = (newState.master as boolean) || null;
        this._patchset = (newState.patchsets as number) || null;


        // These RPCs are only called once during the page's lifetime.
        this._fetchCorporaOnce();
        this._fetchParamSetOnce();
        this._maybeFetchChangelistSummaryOnce(); // Only called if the CL/CRS URL params are set.

        // Called every time the state changes.
        this._fetchSearchResults();

        this._render();
      },
    );
  }

  connectedCallback() {
    super.connectedCallback();
    this._render();

    this._keyDownEventHandlerFn = (event: KeyboardEvent) => this._onKeyDown(event);
    document.addEventListener('keydown', this._keyDownEventHandlerFn);

    this._bulkTriageDialog = this.querySelector('dialog.bulk-triage');
    dialogPolyfill.registerDialog(this._bulkTriageDialog!);

    this._helpDialog = this.querySelector('dialog.help');
    dialogPolyfill.registerDialog(this._helpDialog!);
  }

  disconnectedCallback() {
    super.disconnectedCallback();
    document.removeEventListener('keydown', this._keyDownEventHandlerFn!);
  }

  private async _fetchCorporaOnce() {
    // Only fetch once. We assume this doesn't change during the page's lifetime.
    if (this._corpora.length > 0) return;

    try {
      sendBeginTask(this);
      const statusResponse: StatusResponse =
        await fetch('/json/v1/trstatus', {method: 'GET'}).then(jsonOrThrow);
      this._corpora = statusResponse.corpStatus.map((corpus) => corpus.name);
      this._render();
      sendEndTask(this);
    } catch(e) {
      sendFetchError(this, e, 'fetching the available corpora');
    }
  }

  private async _fetchParamSetOnce(changeListId?: number) {
    // Only fetch once. We assume this doesn't change during the page's lifetime.
    if (Object.keys(this._paramSet).length > 0) return;

    try {
      sendBeginTask(this);
      const paramSetResponse: ParamSetResponse =
        await fetch(
            '/json/v1/paramset' + (changeListId ? '?changelist_id='+  changeListId : ''),
            {method: 'GET'})
          .then(jsonOrThrow);

      // TODO(lovisolo): Type ParamSetResponse is generated by go2ts as
      //                 { [key: string]: string[] | null }, but the real ParamSet type used here is
      //                 { [key: string]: string[] }. Instead of blindly typecasing, perform an
      //                 explicit check that no values are null, then convert to ParamSet.
      //                 Alternatively, add support for overriding a type definition in go2ts.
      this._paramSet = paramSetResponse as ParamSet;

      // Remove the corpus to prevent it from showing up in the search controls left- and right-hand
      // trace filter selectors.
      delete this._paramSet[CORPUS_KEY];

      this._render();
      sendEndTask(this);
    } catch(e) {
      sendFetchError(this, e, 'fetching the available digest parameters');
    }
  }

  private async _maybeFetchChangelistSummaryOnce() {
    // We can skip this RPC if no CL information has been provided via URL parameters.
    if (!this._crs || !this._changelistId) return;

    // Only fetch once. This is OK because the changelist cannot be changed via the UI.
    if (this._changeListSummaryResponse) return;

    try {
      sendBeginTask(this);
      this._changeListSummaryResponse =
        await fetch(`/json/v1/changelist/${this._crs}/${this._changelistId}`, {method: 'GET'})
          .then(jsonOrThrow);
      this._render();
      sendEndTask(this);
    } catch(e) {
      sendFetchError(this, e, 'fetching the changelist summary');
    }
  }

  private _makeSearchRequest() {
    // Utility function to insert the selected corpus into the left- and right-hand trace filters,
    // as required by the /json/v1/search RPC.
    const insertCorpus = (paramSet: ParamSet) => {
      const copy = deepCopy(paramSet);
      copy[CORPUS_KEY] = [this._searchCriteria.corpus];
      return copy;
    }

    // Populate a SearchRequest object, which we'll use to generate the query string for the
    // /json/v1/search RPC.
    const searchRequest: SearchRequest = {
      query: fromParamSet(insertCorpus(this._searchCriteria.leftHandTraceFilter)),
      rquery: fromParamSet(insertCorpus(this._searchCriteria.rightHandTraceFilter)),
      pos: this._searchCriteria.includePositiveDigests,
      neg: this._searchCriteria.includeNegativeDigests,
      unt: this._searchCriteria.includeUntriagedDigests,
      head: !this._searchCriteria.includeDigestsNotAtHead, // Inverted because head = at head only.
      include: this._searchCriteria.includeIgnoredDigests,
      frgbamin: this._searchCriteria.minRGBADelta,
      frgbamax: this._searchCriteria.maxRGBADelta,
      fref: this._searchCriteria.mustHaveReferenceImage,
      sort: this._searchCriteria.sortOrder === 'ascending' ? 'asc' : 'desc',
    };

    // Populate optional query parameters.
    if (this._blame) searchRequest.blame = this._blame;
    if (this._useSQL) searchRequest.use_sql = this._useSQL;
    if (this._crs) searchRequest.crs = this._crs;
    if (this._changelistId) searchRequest.issue = this._changelistId;
    if (this._includeDigestsFromPrimary) searchRequest.master = this._includeDigestsFromPrimary;
    if (this._patchset) searchRequest.patchsets = this._patchset;

    return searchRequest;
  }

  private async _fetchSearchResults() {
    // Force only one fetch at a time. Abort any outstanding requests.
    if (this._searchResultsFetchController) {
      this._searchResultsFetchController.abort();
    }
    this._searchResultsFetchController = new AbortController();

    const searchRequest = this._makeSearchRequest();

    try {
      sendBeginTask(this);
      const searchResponse: SearchResponse =
        await fetch(
            '/json/v1/search?' + fromObject(searchRequest as any),
            {method: 'GET', signal: this._searchResultsFetchController.signal})
          .then(jsonOrThrow);
      this._searchResponse = searchResponse;

      // Reset UI and render.
      this._selectedSearchResultIdx = -1;
      this._render();
      sendEndTask(this);
    } catch(e) {
      sendFetchError(this, e, 'fetching the available digest parameters');
    }
  }

  private _getCurrentPageDigestsTriageRequestData() {
    const triageRequestData: TriageRequestData = {};

    if (!this._searchResponse) return triageRequestData;

    for (const result of this._searchResponse.digests!) {
      let byTest = triageRequestData[result!.test];
      if (!byTest) {
        byTest = {};
        triageRequestData[result!.test] = byTest;
      }
      let valueToSet: Label | '' = '';
      if (result!.closestRef === 'pos') {
        valueToSet = 'positive';
      } else if (result!.closestRef === 'neg') {
        valueToSet = 'negative';
      }
      // Note: We cast this potentially empty string as a Label due to the legacy behaviors
      // documented here:
      // https://github.com/google/skia-buildbot/blob/6dd58fac8d1eac7bbf4e737110605dcdf1b20a56/golden/modules/bulk-triage-sk/bulk-triage-sk.ts#L134
      // TODO(lovisolo): Clean this up after the legacy search-page-sk is removed.
      byTest[result!.digest] = valueToSet as Label;
    }

    return triageRequestData;
  }

  private _onSearchControlsChange(event: CustomEvent<SearchCriteria>) {
    this._searchCriteria = event.detail;
    this._stateChanged!();
    this._fetchSearchResults();

    // Re-render the page immediately so that the link to the legacy search page is updated with the
    // new query parameters. If we don't re-render immediately, said link will briefly fall out of
    // sync until the /json/search RPC resolves and the page is re-rendered with new search results.
    //
    // TODO(lovisolo): Remove after the legacy search page is deleted.
    this._render();
  }

  private _onChangelistControlsChange(event: CustomEvent<ChangelistControlsSkChangeEventDetail>) {
    this._includeDigestsFromPrimary = event.detail.include_master;
    this._patchset = event.detail.ps_order;
    this._stateChanged!();
    this._fetchSearchResults();

    // Re-render the page immediately so that the link to the legacy search page is updated with the
    // new query parameters. If we don't re-render immediately, said link will briefly fall out of
    // sync until the /json/search RPC resolves and the page is re-rendered with new search results.
    //
    // TODO(lovisolo): Remove after the legacy search page is deleted.
    this._render();
  }

  private _onTriage(result: SearchResult, label: Label) {
    // When the user triages a digest, we patch the corresponding cached SearchResult with the new
    // label. This prevents the digest-details-sk component from reverting to the original label
    // when the search-page-sk is re-rendered with the same cached SearchResults.
    result.status = label;
  }

  private _onKeyDown(event: KeyboardEvent) {
    // Ignore all keyboard shortcuts if there are any open modals.
    if (document.querySelectorAll('dialog[open]').length > 0) return;

    switch(event.key) {
      // Next.
      case 'j':
        this._selectSearchResult(this._selectedSearchResultIdx + 1);
        break;

      // Previous.
      case 'k':
        this._selectSearchResult(this._selectedSearchResultIdx - 1);
        break;

      // Zoom in.
      case 'w':
        this._openZoomDialogForSelectedSearchResult();
        break;

      // Mark as positive.
      case 'a':
        this._triageSelectedSearchResult('positive');
        break;

      // Mark as negative.
      case 's':
        this._triageSelectedSearchResult('negative');
        break;

      // Mark as untriaged.
      case 'd':
        this._triageSelectedSearchResult('untriaged');
        break;

      // Show help dialog.
      case '?':
        this._helpDialog?.showModal();
        break;

      default:
        return; // Do not stop propagation if we haven't captured the event.
    }

    event.stopPropagation(); // Stop propagation if we captured the event.
  }

  /**
   * Selects the search result with the given index, i.e. it draws a box around its corresponding
   * digest-details-sk element to indicate focus and scrolls it into view.
   */
  private _selectSearchResult(index: number) {
    const searchResults = this._searchResponse?.digests || [];
    if (index < 0 || index >= searchResults.length) return;

    // We update the selected search result by hand to avoid re-rendering the entire page, which can
    // be very slow if there are many search results.
    this.querySelector<HTMLElement>('digest-details-sk.selected')?.classList.remove('selected');
    this.querySelector<HTMLElement>(`digest-details-sk:nth-child(${index + 1})`)
      ?.classList.add('selected');

    // We also keep track of the selected result so we can correctly add the "selected" CSS class
    // in the lit-html template in case we re-render the page with the cached search results.
    this._selectedSearchResultIdx = index;

    this._getSelectedDigestDetailsSk()!.scrollIntoView();
  }

  /**
   * Applies the given label to the currently selected search result.
   */
  private _triageSelectedSearchResult(label: Label) {
    // TODO(lovisolo): Clean this up once DigestDetailsSk is ported to TypeScript.

    const digestDetailsSk = this._getSelectedDigestDetailsSk();
    if (!digestDetailsSk) return;

    digestDetailsSk.querySelector<HTMLButtonElement>(`triage-sk button.${label}`)!.click();
  }

  /**
   * Opens the zoom dialog of the details-digest-sk element corresponding to the currently selected
   * search result.
   */
  private _openZoomDialogForSelectedSearchResult() {
    // TODO(lovisolo): Clean this up once DigestDetailsSk is ported to TypeScript.

    const digestDetailsSk = this._getSelectedDigestDetailsSk();
    if (!digestDetailsSk) return;

    digestDetailsSk.querySelector<HTMLButtonElement>('button.zoom_btn')!.click();
  }

  /**
   * Returns the digest-details-sk element corresponding to the currently selected search result.
   */
  private _getSelectedDigestDetailsSk() {
    // TODO(lovisolo): Clean this up once DigestDetailsSk is ported to TypeScript.

    if (this._selectedSearchResultIdx < 0) return null;
    return this.querySelector<HTMLElement>(
      `digest-details-sk:nth-child(${this._selectedSearchResultIdx + 1})`);
  }
}

define('search-page-sk', SearchPageSk);
