import { fixture, assert, html, aTimeout, nextFrame } from '@open-wc/testing';
import { AmfDefinitions } from '@api-client/core/build/browser.js';
import { DomEventsAmfStore } from '../../../src/index.js';
import ApiRequestEditorElement from '../../../src/elements/amf/ApiRequestEditor.element.js';
import { OperationParameter } from '../../../src/amf/types.js';
import { AmfLoader } from '../AmfLoader.js';
import '../../../src/define/amf/api-request-editor.js';
import Input from '../../../src/ui/input/Input.js';

describe('ApiRequestEditorElement', () => {
  describe('APIC-289', () => {
    const store = new DomEventsAmfStore(window);
    store.listen();

    after(() => {
      store.unlisten();
    });

    async function modelFixture(selected?: string): Promise<ApiRequestEditorElement> {
      const element = await fixture(html`<api-request-editor .domainId="${selected}"></api-request-editor>`);
      await aTimeout(2);
      return element as ApiRequestEditorElement;
    }

    const apiFile = 'APIC-289';
    let loader: AmfLoader;
    let amf: AmfDefinitions.IAmfDocument;
    before(async () => {
      loader = new AmfLoader();
      amf = await loader.getGraph(apiFile);
      store.amf = amf;
    });

    it('generates query parameters model', async () => {
      const method = loader.lookupOperation(amf, '/organization', 'get') as AmfDefinitions.IAmfOperation;
      const element = await modelFixture(method['@id']);
      await aTimeout(0);
      await aTimeout(0);
      await nextFrame();
      const model = element.amfParameters.parametersValue;
      assert.lengthOf(model, 1);
    });

    it('has an OAS name on a parameter', async () => {
      const method = loader.lookupOperation(amf, '/organization', 'get') as AmfDefinitions.IAmfOperation;
      const element = await modelFixture(method['@id']);
      await aTimeout(0);
      await aTimeout(0);
      await nextFrame();
      const model = element.amfParameters.parametersValue.find(p => p.parameter.name === 'foo_bar') as OperationParameter;
      assert.equal(model.parameter.paramName, 'foo');
    });

    it('renders a parameter name with the input', async () => {
      const method = loader.lookupOperation(amf, '/organization', 'get') as AmfDefinitions.IAmfOperation;
      const element = await modelFixture(method['@id']);
      await aTimeout(0);
      await aTimeout(0);
      await nextFrame();
      const input = element.shadowRoot!.querySelector('.form-input') as Input;
      assert.equal((input.label as string).trim(), 'foo*');
    });
  });
});
