/**
 * @license
 * Copyright 2016 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import * as sinon from 'sinon';
import '../../../test/common-test-setup';
import './gr-editable-label';
import {GrEditableLabel} from './gr-editable-label';
import {queryAndAssert} from '../../../utils/common-util';
import {GrButton} from '../gr-button/gr-button';
import {assert, fixture, html} from '@open-wc/testing';
import {GrAutocomplete} from '../gr-autocomplete/gr-autocomplete';
import {AutocompleteSuggestion} from '../../../utils/autocomplete-util';
import {Key} from '../../../utils/dom-util';
import {pressKey, waitEventLoop, waitUntil} from '../../../test/test-utils';
import {MdMenu} from '@material/web/menu/menu';
import {MdFilledTextField} from '@material/web/textfield/filled-text-field';

suite('gr-editable-label tests', () => {
  let element: GrEditableLabel;
  let elementNoPlaceholder: GrEditableLabel;
  let input: HTMLInputElement;
  let label: HTMLLabelElement;

  setup(async () => {
    element = await fixture<GrEditableLabel>(html`
      <gr-editable-label
        value="value text"
        placeholder="label text"
      ></gr-editable-label>
    `);
    label = queryAndAssert<HTMLLabelElement>(element, 'label');
    elementNoPlaceholder = await fixture<GrEditableLabel>(html`
      <gr-editable-label value=""></gr-editable-label>
    `);

    const mdFilledTextField = queryAndAssert<MdFilledTextField>(
      element,
      '#input'
    );
    input = mdFilledTextField.shadowRoot!.querySelector('input')!;
  });

  test('renders', () => {
    assert.shadowDom.equal(
      element,
      `<div style="position: relative;">
        <label
          aria-label="value text"
          class="editable"
          id="button"
          part="label"
          title="value text"
        >
          value text
        </label>
        <md-menu
          anchor="button"
          aria-hidden="true"
          id="dropdown"
          tabindex="-1"
        >
          <div class="dropdown-content">
            <div
              class="inputContainer"
              part="input-container"
            >
              <md-filled-text-field
                autocomplete=""
                data-aria-label="label text"
                id="input"
                inputmode=""
                placeholder="label text"
                type="text"
              >
              </md-filled-text-field>
              <div class="buttons">
                <gr-button
                  aria-disabled="false"
                  id="saveBtn"
                  primary=""
                  role="button"
                  tabindex="0"
                >
                  Save
                </gr-button>
                <gr-button
                  aria-disabled="false"
                  id="cancelBtn"
                  role="button"
                  tabindex="0"
                >
                  Cancel
                </gr-button>
              </div>
            </div>
          </div>
        </md-menu>
      </div>`
    );
  });

  test('element render', async () => {
    // The dropdown is closed and the label is visible:
    const dropdown = queryAndAssert<MdMenu>(element, '#dropdown');
    assert.isFalse(dropdown.open);
    assert.isTrue(label.classList.contains('editable'));
    assert.equal(label.textContent, 'value text');

    label.click();
    await element.updateComplete;
    // The dropdown is open (which covers up the label):
    assert.isTrue(dropdown.open);
    assert.equal(input.value, 'value text');
  });

  test('title with placeholder', async () => {
    assert.equal(element.title, 'value text');
    element.value = '';

    await element.updateComplete;
    assert.equal(element.title, 'label text');
  });

  test('title without placeholder', async () => {
    assert.equal(elementNoPlaceholder.title, '');
    element.value = 'value text';

    await waitEventLoop();
    assert.equal(element.title, 'value text');
  });

  test('edit value', async () => {
    const editedSpy = sinon.spy();
    element.addEventListener('changed', editedSpy);
    assert.isFalse(element.editing);

    label.click();
    await waitEventLoop();

    assert.isTrue(element.editing);
    assert.isFalse(editedSpy.called);

    element.inputText = 'new text';
    pressKey(input, Key.ENTER);
    await waitEventLoop();

    assert.isTrue(editedSpy.called);
    assert.equal(input.value, 'new text');
    assert.isFalse(element.editing);
  });

  test('save button', async () => {
    const editedSpy = sinon.spy();
    element.addEventListener('changed', editedSpy);
    assert.isFalse(element.editing);

    label.click();
    await waitEventLoop();

    assert.isTrue(element.editing);
    assert.isFalse(editedSpy.called);

    element.inputText = 'new text';
    pressKey(queryAndAssert<GrButton>(element, '#saveBtn'), Key.ENTER);
    await waitEventLoop();

    assert.isTrue(editedSpy.called);
    assert.equal(input.value, 'new text');
    assert.isFalse(element.editing);
  });

  test('edit and then escape key', async () => {
    const editedSpy = sinon.spy();
    element.addEventListener('changed', editedSpy);
    assert.isFalse(element.editing);

    label.click();
    await waitEventLoop();

    assert.isTrue(element.editing);
    assert.isFalse(editedSpy.called);

    element.inputText = 'new text';
    pressKey(input, Key.ESC);
    await waitEventLoop();

    assert.isFalse(editedSpy.called);
    // Text changes should be discarded.
    assert.equal(input.value, 'value text');
    assert.isFalse(element.editing);
  });

  test('cancel button', async () => {
    const editedSpy = sinon.spy();
    element.addEventListener('changed', editedSpy);
    assert.isFalse(element.editing);

    label.click();
    await waitEventLoop();

    assert.isTrue(element.editing);
    assert.isFalse(editedSpy.called);

    element.inputText = 'new text';
    // Press escape:
    queryAndAssert<GrButton>(element, '#cancelBtn').click();
    await waitEventLoop();

    assert.isFalse(editedSpy.called);
    // Text changes should be discarded.
    assert.equal(input.value, 'value text');
    assert.isFalse(element.editing);
  });

  suite('gr-editable-label read-only tests', () => {
    let element: GrEditableLabel;
    let label: HTMLLabelElement;

    setup(async () => {
      element = await fixture<GrEditableLabel>(html`
        <gr-editable-label
          readOnly
          value="value text"
          placeholder="label text"
        ></gr-editable-label>
      `);
      label = queryAndAssert(element, 'label');
    });

    test('disallows edit when read-only', async () => {
      // The dropdown is closed.
      const dropdown = queryAndAssert<MdMenu>(element, '#dropdown');
      assert.isFalse(dropdown.open);
      label.click();

      await element.updateComplete;

      // The dropdown is still closed.
      assert.isFalse(dropdown.open);
    });

    test('label is not marked as editable', () => {
      assert.isFalse(label.classList.contains('editable'));
    });
  });

  suite('autocomplete tests', () => {
    let element: GrEditableLabel;
    let autocomplete: GrAutocomplete;
    let suggestions: Array<AutocompleteSuggestion>;
    let labelSaved = false;

    setup(async () => {
      element = await fixture<GrEditableLabel>(html`
        <gr-editable-label
          autocomplete
          value="value text"
          .query=${() => Promise.resolve(suggestions)}
          @changed=${() => {
            labelSaved = true;
          }}
        ></gr-editable-label>
      `);

      autocomplete = element.grAutocomplete!;
      autocomplete.debounceWait = 10;
    });

    test('autocomplete suggestions shown esc closes suggestions', async () => {
      suggestions = [{name: 'value text 1'}, {name: 'value text 2'}];
      await element.open();

      await waitUntil(() => !autocomplete.suggestionsDropdown!.isHidden);

      pressKey(autocomplete.input!, Key.ESC);

      await waitUntil(() => autocomplete.suggestionsDropdown!.isHidden);
      assert.isTrue(element.dropdown?.open);
    });

    test('autocomplete suggestions closed esc closes dialogue', async () => {
      suggestions = [{name: 'value text 1'}, {name: 'value text 2'}];
      await element.open();
      await waitUntil(() => !autocomplete.suggestionsDropdown!.isHidden);
      // Press esc to close suggestions.
      pressKey(autocomplete.input!, Key.ESC);
      await waitUntil(() => autocomplete.suggestionsDropdown!.isHidden);

      pressKey(autocomplete.input!, Key.ESC);

      await element.updateComplete;
      // Dialogue is closed, save not triggered.
      assert.isTrue(autocomplete.suggestionsDropdown?.isHidden);
      assert.isFalse(element.dropdown?.open);
      assert.isFalse(labelSaved);
    });

    test('autocomplete suggestions shown enter chooses suggestions', async () => {
      suggestions = [{name: 'value text 1'}, {name: 'value text 2'}];
      await element.open();

      // Waiting until dropdown not hidden, will ensure dialog is open and input
      // is focused, but not that the suggestion has loaded.
      await waitUntil(() => !autocomplete.suggestionsDropdown!.isHidden);
      await autocomplete.latestSuggestionUpdateComplete;

      pressKey(autocomplete.input!, Key.ENTER);

      await waitUntil(() => autocomplete.suggestionsDropdown!.isHidden);
      await element.updateComplete;
      // The value was picked from suggestions, suggestions are hidden, dialogue
      // is shown, save has not been triggered.
      assert.strictEqual(element.inputText, 'value text 1');
      assert.isTrue(autocomplete.suggestionsDropdown?.isHidden);
      assert.isTrue(element.dropdown?.open);
      assert.isFalse(labelSaved);
    });

    test('autocomplete suggestions closed enter saves suggestion', async () => {
      suggestions = [{name: 'value text 1'}, {name: 'value text 2'}];
      await element.open();
      // Waiting until dropdown not hidden, will ensure dialog is open and input
      // is focused, but not that the suggestion has loaded.
      await waitUntil(() => !autocomplete.suggestionsDropdown!.isHidden);
      await autocomplete.latestSuggestionUpdateComplete;

      // Press enter to close suggestions.
      pressKey(autocomplete.input!, Key.ENTER);

      await waitUntil(() => autocomplete.suggestionsDropdown!.isHidden);

      pressKey(autocomplete.input!, Key.ENTER);

      await element.updateComplete;
      // Dialogue is closed, save triggered.
      assert.isTrue(autocomplete.suggestionsDropdown?.isHidden);
      assert.isFalse(element.dropdown?.open);
      assert.isTrue(labelSaved);
    });
  });
});
