import { html, TemplateResult } from 'lit'
import { AmfDemoPage } from './lib/AmfDemoPage.js'
import { reactive } from '../../src/decorators/index.js'
import type { ApiNavigationEvent } from '../../src/events/amf/NavigationEvents.js'
import type { SelectionType } from '../../src/amf/types.js'
import '../../src/define/amf/api-request.js'
import '../../src/define/amf/api-documentation.js'
import '../../src/md/checkbox/ui-checkbox.js'
import '../../src/md/dialog/ui-dialog.js'
import '../../src/md/button/ui-text-button.js'
import '../../src/md/list/ui-list-item.js'

class ComponentDemo extends AmfDemoPage {
  @reactive() accessor editorOpened: boolean

  @reactive() accessor editorOperation: string | undefined

  @reactive() accessor domainId: string | undefined

  @reactive() accessor domainType: SelectionType | undefined

  @reactive() accessor operationId: string | undefined

  @reactive() accessor tryItButton: boolean | undefined

  @reactive() accessor tryItPanel: boolean | undefined

  @reactive() accessor overrideBaseUri: boolean | undefined

  @reactive() accessor renderCustomServer: boolean | undefined

  @reactive() accessor noServerSelector: boolean | undefined

  @reactive() accessor allowCustomBaseUri: boolean | undefined

  constructor() {
    super()

    this.editorOpened = false
    this.tryItButton = true
    this.componentName = 'api-documentation'
    ;[
      ['httpbin', 'httpbin.org'],
      ['google-drive-api', 'Google Drive'],
      ['multi-server', 'Multiple servers'],
      ['array-body', 'Body with array test case'],
      ['nexmo-sms-api', 'Nexmo SMS API'],
      ['appian-api', 'Applian API'],
      ['APIC-15', 'APIC-15'],
      ['oauth1-fragment', 'OAuth 1 fragment'],
      ['oauth2-fragment', 'OAuth 2 fragment'],
      ['documentation-fragment', 'Documentation fragment'],
      ['type-fragment', 'Type fragment'],
      ['lib-fragment', 'Library fragment'],
      ['SE-10469', 'SE-10469'],
      ['SE-11415', 'SE-11415'],
      ['async-api', 'async-api'],
      ['APIC-711', 'APIC-711: switching to a library'],
    ].forEach(([file, label]) => {
      this.apis.push({
        file: `models/${file}.json`,
        label,
      })
    })
    this.autoLoad()
  }

  override _apiChanged(e: CustomEvent): void {
    this.domainId = 'summary'
    this.domainType = 'summary'
    super._apiChanged(e)
  }

  override _navChanged(e: ApiNavigationEvent): void {
    const { domainId, domainType, parentId, passive } = e.detail
    if (passive === true) {
      return
    }
    this.domainType = domainType
    if (domainType === 'operation') {
      this.operationId = domainId
      this.domainId = parentId
    } else {
      this.operationId = undefined
      this.domainId = domainId
    }

    //
    // Here your application can be smart and determine
    // the domainId and type for fragments and partial models
    // so when the API is loaded it shows a specific value.
    //
  }

  tryitHandler(e: CustomEvent): void {
    const { id } = e.detail
    this.editorOperation = id
    this.editorOpened = true
  }

  editorCloseHandler(): void {
    this.editorOperation = undefined
    this.editorOpened = false
  }

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

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

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

  componentTemplate(): TemplateResult {
    let finalBaseUri: string | undefined
    if (this.overrideBaseUri) {
      finalBaseUri = 'https://custom.api.com'
    }
    return html`
      <section class="demo-section">
        <api-documentation
          .domainId="${this.domainId}"
          .operationId="${this.operationId}"
          .domainType="${this.domainType}"
          .redirectUri="${this.redirectUri}"
          .tryItPanel="${this.tryItPanel}"
          .tryItButton="${this.tryItButton}"
          .noServerSelector="${this.noServerSelector}"
          .allowCustomBaseUri="${this.allowCustomBaseUri}"
          .baseUri="${finalBaseUri}"
          @tryit="${this.tryitHandler}"
          handleNavigationEvents
        >
          ${this._addCustomServers()}
        </api-documentation>
      </section>

      <section class="demo-section">
        <h2>View control</h2>
        <p class="block" id="mainOptionsLabel">Options</p>
        <label class="label-large">
          <ui-checkbox
            @change="${this._toggleBooleanOption}"
            ?checked="${this.tryItButton}"
            name="tryItButton"
            aria-describedby="mainOptionsLabel"
          ></ui-checkbox>
          Render try it
        </label>

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

        <label class="label-large">
          <ui-checkbox
            @change="${this._toggleBooleanOption}"
            ?checked="${this.overrideBaseUri}"
            name="overrideBaseUri"
            aria-describedby="mainOptionsLabel"
            title="Sets the base URI to a pre-defined value."
          ></ui-checkbox>
          Custom base URI
        </label>

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

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

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

  _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>
    `
  }

  requestEditorDialogTemplate(): TemplateResult {
    return html`
      <ui-dialog modal @close="${this.editorCloseHandler}" .open="${this.editorOpened}" class="request-dialog">
        <span slot="title">API request</span>
        <api-request
          .domainId="${this.editorOperation}"
          urlLabel
          applyAuthorization
          allowHideOptional
          .redirectUri="${this.redirectUri}"
        >
        </api-request>
        <ui-text-button slot="button" value="dismiss">Close</ui-text-button>
      </ui-dialog>
    `
  }
}
const instance = new ComponentDemo()
instance.render()
