import { CSSResult, html, TemplateResult } from 'lit'
import { ProjectMock } from '@api-client/core/mocking/ProjectMock.js'
import { HttpRequest, type IHttpRequest } from '@api-client/core/models/HttpRequest.js'
import type { IRequestAuthorization } from '@api-client/core/models/RequestAuthorization.js'
import type { IRequestUiMeta } from '@api-client/core/models/RequestUiMeta.js'
import { DemoPage } from '../../../src/demo/DemoPage.js'
import { reactive } from '../../../src/decorators/index.js'
import surfaceStyles from '../../../src/styles/m3/surface.module.js'
// import { WebHttpClientStoreBindings } from '../../../src/bindings/web/WebHttpClientStoreBindings.js'
// import { WebProxyBindings } from '../../../src/bindings/web/WebProxyBindings.js'
import RequestEditor, { SendDetails } from '../../../src/elements/http/RequestEditor.js'
// import env from '../../env.js'
import '../../../src/define/http/http-request-editor.js'

const REQUEST_STORE_KEY = 'demo.request-ui.editor.request-data'
const AUTH_STORE_KEY = 'demo.request-ui.editor.request-auth'
const UI_STORE_KEY = 'demo.request-ui.editor.request-ui'

// const workerUri = new URL('/src/http-client/store/IdbThread.ts', import.meta.url).toString()

// const AppInfo: IApplication = { code: 'demo', name: 'Demo', version: '0' }

class ComponentDemoPage extends DemoPage {
  static override get styles(): CSSResult[] {
    return [...DemoPage.styles, surfaceStyles]
  }

  override accessor componentName = 'http-request-editor'

  mock = new ProjectMock()

  @reactive() accessor request = new HttpRequest().toJSON()

  @reactive() accessor auth: IRequestAuthorization[] | undefined

  @reactive() accessor ui: IRequestUiMeta = {}

  @reactive() accessor initialized: boolean

  oauth2RedirectUri = 'https://auth.advancedrestclient.com/arc.html'

  oauth2AuthorizationUri = `${window.location.protocol}//${window.location.host}${window.location.pathname}oauth-authorize.html`

  // store = new WebHttpClientStoreBindings(AppInfo, workerUri)

  // http = new WebProxyBindings(AppInfo, `${env.proxyUri}/open`)

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

  async init(): Promise<void> {
    // await this.store.initialize()
    // await this.http.initialize()
    await this.loadMonaco()
    await this.restoreRequest()
    await this.restoreAuth()
    await this.restoreUi()
    this.initialized = true
  }

  async restoreRequest(): Promise<void> {
    const data = localStorage.getItem(REQUEST_STORE_KEY)
    if (!data) {
      return
    }
    try {
      const tmp = JSON.parse(data)
      if (tmp) {
        const request = tmp as IHttpRequest
        this.request = request
      }
    } catch {
      //
    }
  }

  async restoreAuth(): Promise<void> {
    const data = localStorage.getItem(AUTH_STORE_KEY)
    if (!data) {
      return
    }
    try {
      const tmp = JSON.parse(data)
      if (Array.isArray(tmp)) {
        this.auth = tmp
      }
    } catch {
      //
    }
  }

  async restoreUi(): Promise<void> {
    const data = localStorage.getItem(UI_STORE_KEY)
    if (!data) {
      return
    }
    try {
      const tmp = JSON.parse(data)
      if (tmp) {
        this.ui = tmp
      }
    } catch {
      //
    }
  }

  async handleChange(e: Event): Promise<void> {
    const editor = e.target as RequestEditor
    const request = await editor.serialize()
    this.request = request
    localStorage.setItem(REQUEST_STORE_KEY, JSON.stringify(request))
    console.log('request change', request)
  }

  handleAuthorizationChange(e: Event): void {
    const editor = e.target as RequestEditor
    this.auth = editor.authorization
    if (editor.authorization) {
      localStorage.setItem(AUTH_STORE_KEY, JSON.stringify(editor.authorization))
    } else {
      localStorage.removeItem(AUTH_STORE_KEY)
    }
    console.log('auth change', editor.authorization)
  }

  handleUiChange(e: Event): void {
    const editor = e.target as RequestEditor
    if (!editor.ui) {
      return
    }
    this.ui = editor.ui
    if (editor.ui) {
      localStorage.setItem(UI_STORE_KEY, JSON.stringify(editor.ui))
    } else {
      localStorage.removeItem(UI_STORE_KEY)
    }
    console.log('ui change', editor.ui)
  }

  handleSend(e: CustomEvent<SendDetails>): void {
    this.send(e.detail)
  }

  async send(sendInfo: SendDetails): Promise<void> {
    console.log(sendInfo)
    throw new Error(`Not implemented`)
    // const { request, assertions, authorization, config } = sendInfo
    // const init: IRequestProxyInit = {
    //   kind: HttpRequestKind,
    //   request,
    //   assertions,
    //   authorization,
    //   config,
    // }
    // const result = await this.http.coreRequest(init)
    // console.log(result.result.response)
  }

  contentTemplate(): TemplateResult {
    if (!this.initialized) {
      return html`
        <a href="./">Back</a>
        <div class="screen-loader">
          <p>Loading demo page</p>
          <progress></progress>
        </div>
      `
    }
    const { request, auth, ui } = this
    return html`
      <a href="./">Back</a>
      <section class="demo-section">
        <h2 class="title-large">HTTP request editor</h2>

        <div class="editor-wrapper surface1">
          <http-request-editor
            .request="${request}"
            .authorization="${auth}"
            .ui="${ui}"
            .oauth2RedirectUri="${this.oauth2RedirectUri}"
            .oauth2AuthorizationUri="${this.oauth2AuthorizationUri}"
            @change="${this.handleChange}"
            @authorizationchange="${this.handleAuthorizationChange}"
            @uichange="${this.handleUiChange}"
            @send="${this.handleSend}"
          ></http-request-editor>
        </div>
      </section>
    `
  }
}

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