/**
 * @module modules/filter-dialog-sk
 * @description <h2><code>filter-dialog-sk</code></h2>
 *
 * A dialog that provides input elements to filter search results by metric values.
 *
 * Events:
 *   edit: Emitted when the user clicks the "Filter" button (and closes the dialog in the process).
 *         The "detail" field of the event contains the filter values entered by the user.
 */

import { define } from 'elements-sk/define';
import { html } from 'lit-html';
import { live } from 'lit-html/directives/live';
import { ElementSk } from '../../../infra-sk/modules/ElementSk';
import dialogPolyfill from 'dialog-polyfill';
import { $$ } from 'common-sk/modules/dom';
import { deepCopy } from 'common-sk/modules/object';
import { ParamSet } from 'common-sk/modules/query';

import 'elements-sk/styles/buttons';
import 'elements-sk/checkbox-sk';
import '../trace-filter-sk';
import '../../../infra-sk/modules/paramset-sk';

export interface Filters {
  diffConfig: ParamSet;
  minRGBADelta: number; // Valid values are integers from 0 to 255.
  maxRGBADelta: number; // Valid values are integers from 0 to 255.
  sortOrder: 'ascending' | 'descending';
  mustHaveReferenceImage: boolean;
};

// This template produces an <input type=range> (a "slider") and an <input type=number> that
// reflect each other's values. When one changes, the other is updated with the new value, and
// viceversa.
const numericParamTemplate = (id: string,
                              label: string,
                              setterFn: (value: number) => void,
                              value: number = 0,
                              min: number,
                              max: number,
                              step: number) => {
  const onInput = (e: InputEvent) => {
    const target = e.target as HTMLInputElement;

    // Set the corresponding field in the FilterDialogSk instance.
    setterFn(parseFloat(target.value));

    // Sync up the range and number inputs.
    const otherSelector = `input[type="${target.type === 'range' ? 'number' : 'range'}"]`;
    const other = target.parentElement!.querySelector<HTMLInputElement>(otherSelector)!;
    other.value = target.value;
  };

  // Please see the note on the FilterDialogSk's template regarding the live() directive.
  return html`
    <label for="${id}">${label}</label>
    <div class=numeric-param
         id=${id}-numeric-param>
      <input type=range
             id=${id}
             .value=${live(value.toString())}
             min=${min}
             max=${max}
             step=${step}
             @input=${onInput}/>
      <input type=number
             .value=${live(value.toString())}
             min=${min}
             max=${max}
             step=${step}
             @input=${onInput}/>
    </div>`;
}

export class FilterDialogSk extends ElementSk {

  // The live() directive is required because the value attributes will change outside of lit-html,
  // e.g. on user input. Without it, said attributes won't be updated next time this template is
  // rendered with the same bound values, leaving the user's input intact.
  //
  // Concrete example: without the live() directives, if the user opens the dialog, makes changes,
  // cancels and reopens the dialog, the user will see their previous input, when the expected
  // behavior is for their previous input to be discarded.
  private static _template = (el: FilterDialogSk) => html`
    <dialog class=filter-dialog>
      <div class=content>
        <span class=label>Right-hand traces:</span>
        <trace-filter-sk .paramSet=${el._paramSet!}
                         .selection=${live(el._filters?.diffConfig || {})}
                         @trace-filter-sk-change=${el._onTraceFilterSkChange}>
        </trace-filter-sk>

        ${numericParamTemplate(
          'min-rgba-delta',
          'Min RGBA delta:',
          /* setterFn= */ (val) => el._filters!.minRGBADelta = val,
          /* value= */ el._filters?.minRGBADelta,
          /* min= */ 0,
          /* max= */ 255,
          /* step= */ 1)}

        ${numericParamTemplate(
          'max-rgba-delta',
          'Max RGBA delta:',
          /* setterFn= */ (val) => el._filters!.maxRGBADelta = val,
          /* value= */ el._filters?.maxRGBADelta,
          /* min= */ 0,
          /* max= */ 255,
          /* step= */ 1)}

        <label for=sort-order>Sort order:</label>
        <select id=sort-order
                .value=${live(el._filters?.sortOrder)}
                @change=${el._sortOrderChanged}>
          <option value=ascending>Ascending</option>
          <option value=descending>Descending</option>
        </select>

        <checkbox-sk id=must-have-reference-image
                     label="Must have a reference image."
                     ?checked=${live(el._filters?.mustHaveReferenceImage)}
                     @change=${el._mustHaveReferenceImageChanged}>
        </checkbox-sk>
      </div>

      <div class=buttons>
        <button class="filter action" @click=${el._filterBtnClicked}>Apply</button>
        <button class=cancel @click=${el._cancelBtnClicked}>Cancel</button>
      </div>
    </dialog>`;

  private _dialog: HTMLDialogElement | null = null;

  private _paramSet: ParamSet | null = null;
  private _filters: Filters | null = null;

  constructor() {
    super(FilterDialogSk._template);
  }

  connectedCallback() {
    super.connectedCallback();
    this._render();
    this._dialog = $$('dialog.filter-dialog', this);
    dialogPolyfill.registerDialog(this._dialog!);
  }

  open(paramSet: ParamSet, filters: Filters) {
    this._paramSet = paramSet;

    // We make a copy of the caller's filter object because the filter object gets updated on user
    // input, and if the user clicks the "Cancel" button after making some changes, we want the
    // caller's filter object to remain intact.
    this._filters = deepCopy(filters);

    this._render();
    this._dialog?.showModal();
  }

  private _onTraceFilterSkChange(e: CustomEvent<ParamSet>) {
    e.stopPropagation();
    this._filters!.diffConfig = e.detail;
    this._render();
  }

  private _sortOrderChanged(e: InputEvent) {
    const value = (e.target as HTMLSelectElement).value as 'ascending' | 'descending';
    this._filters!.sortOrder = value;
  }

  private _mustHaveReferenceImageChanged(e: InputEvent) {
    const value = (e.target as HTMLInputElement).checked;
    this._filters!.mustHaveReferenceImage = value;
  }

  private _filterBtnClicked() {
    this._dialog!.close();
    this.dispatchEvent(new CustomEvent<Filters>('edit', {
      bubbles: true,
      detail: this._filters!
    }));
  }

  private _cancelBtnClicked() {
    this._dialog!.close();
  }
}

define('filter-dialog-sk', FilterDialogSk);
