import { html, TemplateResult } from 'lit';
import { AmfDemoPage } from './lib/AmfDemoPage.js';
import { reactive } from '../../src/lib/decorators.js';
import { AmfTypes, ApiNavigationEvent, ApiResponseEvent } from '../../src/index.js';
import '../../src/define/amf/api-request-editor.js';
import '../../src/define/ui/ui-checkbox.js';
import '../../src/define/ui/ui-list-item.js';
import '../../src/define/ui/ui-button.js';

class ComponentDemo extends AmfDemoPage {
  @reactive() domainId?: string;

  @reactive() domainType?: AmfTypes.SelectionType;

  @reactive() allowCustom: boolean;

  @reactive() allowCustomBaseUri: boolean;

  @reactive() allowHideOptional: boolean;

  @reactive() urlLabel: boolean;

  @reactive() urlEditor: boolean;

  @reactive() renderCustomServer: boolean;

  @reactive() noServerSelector: boolean;

  @reactive() responseBody?: string;

  constructor() {
    super();
    this.componentName = 'api-request-editor';
    this.allowCustom = true;
    this.allowCustomBaseUri = false;
    this.allowHideOptional = true;
    this.urlLabel = false;
    this.urlEditor = true;
    this.renderCustomServer = false;
    this.noServerSelector = false;

    [
      ['google-drive-api', 'Google Drive'],
      ['multi-server', 'Multiple servers'],
      ['httpbin', 'httpbin.org'],
      ['APIC-168', 'APIC-168: Custom scheme support'],
      ['apic-169', 'apic-169'],
      ['APIC-289', 'APIC-289: OAS param names'],
      ['APIC-298', 'APIC-298: OAS param names 2'],
      ['APIC-480', 'APIC-480'],
      ['APIC-613', 'APIC-613'],
      ['APIC-689', 'APIC-689: Enum values'],
      ['SE-12042', 'SE-12042: Default values issue'],
      ['SE-12224', 'SE-12224: Scope is not an array issues'],
      ['SE-12957', 'SE-12957: OAS query parameters documentation'],
      ['api-keys', 'API key'],
      ['oas-demo', 'OAS Demo API'],
      ['oauth-flows', 'OAS OAuth Flow'],
      ['oas-bearer', 'OAS Bearer'],
      ['secured-api', 'Security demo'],
      ['21143', '21143'],
      ['annotated-parameters', 'annotated-parameters'],
    ].forEach(([file, label]) => {
      this.apis.push({
        file: `models/${file}.json`,
        label,
      })
    });

    this.autoLoad();
  }

  async _loadFile(file: string): Promise<void> {
    await super._loadFile(file);
    this.domainId = undefined;
    this.domainType = undefined;
  }

  _navChanged(e: ApiNavigationEvent): void {
    this.domainId = undefined;
    this.responseBody = undefined;
    const { domainId, domainType } = e.detail;
    if (domainType === 'operation') {
      this.domainId = domainId;
      this.domainType = domainType;
    }
  }

  _responseReady(e: ApiResponseEvent): void {
    const { isError, response } = e.detail;
    if (isError) {
      this.responseBody = 'Error in response';
    } else {
      this.responseBody = response.payload as string;
    }
  }

  requestChangeHandler(): void {
    console.log('requestChangeHandler');
  }

  dispatchAnnotations(): void {
    const detail = { 
      values: [
        { annotationName: 'credentialType', annotationValue: 'id', fieldValue: 'test value 1' },
        { annotationName: 'credentialType', annotationValue: 'secret', fieldValue: 'test value 2' },
      ] 
    };
    document.dispatchEvent(new CustomEvent('populate_annotated_fields', { detail, bubbles: true }));
  }

  _addCustomServers(): TemplateResult | string {
    if (!this.renderCustomServer) {
      return '';
    }
    return html`
    <div class="other-section" slot="custom-base-uri">Other options</div>
    <ui-list-item slot="custom-base-uri" data-value="http://mocking.com">Mocking service</ui-list-item>
    <ui-list-item slot="custom-base-uri" data-value="http://customServer.com2">Custom instance</ui-list-item>
    `;
  }

  _annotationsEventTemplate(): TemplateResult {
    return html `
      <section class="demo-section">
        <h3>Annotations event</h3>
        <p>
          Dispatch event to update values from annotations.
          <ui-button @click="${this.dispatchAnnotations}">Dispatch</ui-button>
        </p>
      </section>
    `;
  }

  contentTemplate(): TemplateResult {
    return html`
    <a href="./">Back</a>
    ${this.demoTemplate()}
    ${this._annotationsEventTemplate()}
    `;
  }

  demoTemplate(): TemplateResult {
    const { loaded } = this;
    return html `
    ${!loaded ? html`<p>Load an API model first.</p>` : this.loadedTemplate()}
    `;
  }

  loadedTemplate(): TemplateResult {
    return html`
    ${this.componentTemplate()}
    `;
  }

  componentTemplate(): TemplateResult {
    const {
      redirectUri,
      allowCustom,
      allowHideOptional,
      domainId,
      responseBody,
      urlLabel,
      urlEditor,
      noServerSelector,
      allowCustomBaseUri,
    } = this;
    return html`
    <section class="demo-section">
      <api-request-editor
        .domainId="${domainId}"
        ?allowCustom="${allowCustom}"
        ?allowHideOptional="${allowHideOptional}"
        ?urlLabel="${urlLabel}"
        ?urlEditor="${urlEditor}"
        .redirectUri="${redirectUri}"
        ?noServerSelector="${noServerSelector}"
        ?allowCustomBaseUri="${allowCustomBaseUri}"
        @change="${this.requestChangeHandler}"
      >
        ${this._addCustomServers()}
      </api-request-editor>
      ${responseBody ? html`<h3>Latest response</h3>
      <output class="response-output" tabindex="0">${responseBody}</output>` : ''}
    </section>

    <section class="demo-section">

      <p id="mainOptionsLabel">Element options</p>

      <label class="label-large">
        <ui-checkbox
          @change="${this._toggleBooleanOption}" 
          ?checked="${allowCustom}"
          name="allowCustom"
          aria-describedby="mainOptionsLabel"
          aria-label="Allow custom"
        ></ui-checkbox>
        Allow custom
      </label>

      <label class="label-large">
        <ui-checkbox
          @change="${this._toggleBooleanOption}" 
          ?checked="${allowHideOptional}"
          name="allowHideOptional"
          aria-describedby="mainOptionsLabel"
          aria-label="Allow hide optional"
        ></ui-checkbox>
        Allow hide optional
      </label>

      <label class="label-large">
        <ui-checkbox
          @change="${this._toggleBooleanOption}" 
          ?checked="${urlLabel}"
          name="urlLabel"
          aria-describedby="mainOptionsLabel"
          aria-label="URL label"
        ></ui-checkbox>
        URL label
      </label>

      <label class="label-large">
        <ui-checkbox
          @change="${this._toggleBooleanOption}" 
          ?checked="${urlEditor}"
          name="urlEditor"
          aria-describedby="mainOptionsLabel"
          aria-label="URL editor"
        ></ui-checkbox>
        URL editor
      </label>

      <label class="label-large">
        <ui-checkbox
          @change="${this._toggleBooleanOption}" 
          ?checked="${this.renderCustomServer}"
          name="renderCustomServer"
          aria-describedby="mainOptionsLabel"
          aria-label="Custom servers"
        ></ui-checkbox>
        Custom servers
      </label>

      <label class="label-large">
        <ui-checkbox
          @change="${this._toggleBooleanOption}" 
          ?checked="${allowCustomBaseUri}"
          name="allowCustomBaseUri"
          aria-describedby="mainOptionsLabel"
          aria-label="Custom Base Uri"
        ></ui-checkbox>
        Custom Base Uri
      </label>

      <label class="label-large">
        <ui-checkbox
          @change="${this._toggleBooleanOption}" 
          ?checked="${noServerSelector}"
          name="noServerSelector"
          aria-describedby="mainOptionsLabel"
          aria-label="Remove Server Selector"
        ></ui-checkbox>
        Remove Server Selector
      </label>
    </section>
    `;
  }
}
const instance = new ComponentDemo();
instance.render();
