import { html, TemplateResult } from 'lit'
import { AmfMixin } from '@api-client/core/amf/AmfMixin.js'
import { AmfSerializer } from '@api-client/core/amf/AmfSerializer.js'
import type { IApiCustomDomainProperty } from '@api-client/core/amf/definitions/Base.js'
import { AmfDemoPage } from './lib/AmfDemoPage.js'
import { reactive } from '../../src/decorators/index.js'
import type { ApiNavigationEvent } from '../../src/events/amf/NavigationEvents.js'
import '../../src/define/amf/api-annotation-document.js'
import '../../src/md/checkbox/ui-checkbox.js'

class AmfHelper extends AmfMixin(Object) {}

class ComponentPage extends AmfDemoPage {
  @reactive() accessor shape: IApiCustomDomainProperty[] | undefined

  serializer: AmfSerializer

  constructor() {
    super()
    this.serializer = new AmfSerializer()
    this.componentName = 'api-annotation-document'
    this.apis = [
      {
        file: 'models/annotated-api.json',
        label: 'Annotated API',
      },
    ]
    this.autoLoad()
  }

  override async _loadFile(file: string): Promise<void> {
    await super._loadFile(file)
    this.serializer.amf = this.amf
  }

  override _navChanged(e: ApiNavigationEvent): void {
    const { domainId, domainType } = e.detail
    if (domainType === 'schema') {
      this.setTypeData(domainId)
    } else if (domainType === 'resource') {
      this.setEndpointData(domainId)
    } else if (domainType === 'operation') {
      this.setMethodData(domainId)
    } else {
      this.shape = undefined
    }
  }

  setTypeData(id: string): void {
    const helper = new AmfHelper()
    helper.amf = this.amf

    const declares = helper._computeDeclares(helper.amf)
    if (!declares) {
      console.error('Declaration not found')
      return
    }
    const shape = declares.find((item) => item['@id'] === id)
    if (!shape) {
      console.error('Type not found')
      return
    }
    this.shape = this.serializer.customDomainProperties(shape)
  }

  setEndpointData(id: string): void {
    const helper = new AmfHelper()
    helper.amf = this.amf

    const webApi = helper._computeWebApi(helper.amf)
    const shape = helper._computeEndpointModel(webApi, id)
    if (shape) {
      this.shape = this.serializer.customDomainProperties(shape)
    } else {
      this.shape = undefined
    }
  }

  setMethodData(id: string): void {
    const helper = new AmfHelper()
    helper.amf = this.amf

    const webApi = helper._computeWebApi(helper.amf)
    const shape = helper._computeMethodModel(webApi, id)
    if (shape) {
      this.shape = this.serializer.customDomainProperties(shape)
    } else {
      this.shape = undefined
    }
  }

  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 {
    const { shape } = this
    if (!shape) {
      return html`<p>Select API object in the navigation</p>`
    }
    return html`
      <section class="demo-section">
        <api-annotation-document .customProperties="${shape}" slot="content"></api-annotation-document>
      </section>
    `
  }
}
const instance = new ComponentPage()
instance.render()
