import { html, TemplateResult } from 'lit'
import { RequestUiMeta } from '@api-client/core/models/RequestUiMeta.js'
import { live } from 'lit/directives/live.js'
import { ifDefined } from 'lit/directives/if-defined.js'
import { DemoPage } from '../../../src/demo/DemoPage.js'
import { reactive } from '../../../src/decorators/index.js'
import BodyEditor from '../../../src/elements/http/BodyEditor.js'
import Input from '../../../src/md/input/Input.js'
import { Events } from '../../../src/events/Events.js'
import '../../../src/define/http/http-body-editor.js'
import '../../../src/md/text-field/ui-filled-text-field.js'

const STORE_KEY = 'demo.request-ui.editor.body'

class ComponentDemoPage extends DemoPage {
  override accessor componentName = 'Body Editing'

  @reactive() accessor contentType: string | undefined

  @reactive() accessor initialized: boolean

  @reactive() accessor ui = new RequestUiMeta()

  @reactive() accessor payload: unknown | undefined

  constructor() {
    super()
    this.initialized = false
    this.init()
  }

  async init(): Promise<void> {
    await this.loadMonaco()
    this.restoreModel()
    this.initialized = true
  }

  restoreModel(): void {
    const data = localStorage.getItem(STORE_KEY)
    if (!data) {
      return
    }
    try {
      this.ui = new RequestUiMeta(data)
    } catch {
      //
    }
  }

  storeModel(): void {
    const { ui } = this
    localStorage.setItem(STORE_KEY, JSON.stringify(ui))
  }

  handleChange(e: Event): void {
    const body = e.target as BodyEditor
    const { value, model, selected } = body
    if (!this.ui.body) {
      this.ui.body = {}
    }
    this.ui.body.model = model
    this.ui.body.selected = selected
    this.payload = value

    console.log('Change from the editor', value, model, selected)
    this.storeModel()
  }

  handleContentType(e: Event): void {
    const input = e.target as Input
    this.contentType = input.value
    Events.Http.Request.State.contentTypeChange(input.value)
  }

  contentTemplate(): TemplateResult {
    if (!this.initialized) {
      return html`
        <a href="./">Back</a>
        <div class="screen-loader">
          <p>Loading demo page</p>
          <progress></progress>
        </div>
      `
    }
    const { body } = this.ui
    const selected = body && (body.selected as 'file' | 'raw' | 'urlEncode' | 'multipart')
    const model = body && body.model

    return html`
      <a href="./">Back</a>
      <section class="demo-section">
        <h2 class="title-large">Setup</h2>
        <ui-filled-text-field
          label="Content type"
          .value="${live(this.contentType || '')}"
          @change="${this.handleContentType}"
        ></ui-filled-text-field>
      </section>
      <section class="demo-section">
        <h2 class="title-large">HTTP body editor</h2>
        <http-body-editor
          .contentType="${this.contentType}"
          .model="${model}"
          .value="${(!model && this.payload) || undefined}"
          selected="${ifDefined(selected)}"
          @change="${this.handleChange}"
          @select="${this.handleChange}"
        ></http-body-editor>
      </section>
    `
  }
}

const instance = new ComponentDemoPage()
instance.render()
