import { html, TemplateResult } from 'lit';
import { IRequestAuthorization, RequestAuthorization, ProjectMock, ISpace, CertificateFile } from '@api-client/core/build/browser.js';
import { reactive } from '../../../src/lib/decorators.js';
import { DemoPage } from '../../../src/pages/demo/DemoPage.js';
import { Authorization } from '../../../src/elements/authorization/ui/Authorization.js';
import { WebStoreBindings } from '../../../src/bindings/web/WebStoreBindings.js';
import { WebConfigurationBindings } from '../../../src/bindings/web/WebConfigurationBindings.js';
import AppInfo from '../../../src/pages/api-client/AppInfo.js';
import '../../../src/define/authorization/cc-authorization.js';

const configUri = new URL('/demo/lib/io/AppConfig.ts', import.meta.url).toString();

const STORE_KEY = 'demo.authorization.editor.cc';

class ComponentDemoPage extends DemoPage {
  componentName = 'Client certificate';

  @reactive() authorization: IRequestAuthorization;

  mocking = new ProjectMock();

  @reactive() initialized = false;

  store = new WebStoreBindings(AppInfo, `http://localhost:8550/v1`);

  config = new WebConfigurationBindings(AppInfo, configUri);

  space?: ISpace;

  constructor() {
    super();
    this.store.space = 'demo-space';

    this.restoreAuth();
    if (!this.authorization) {
      const auth = RequestAuthorization.fromTypedConfig('client certificate', {}, false);
      this.authorization = auth.toJSON();
    }
  }

  async initialize(): Promise<void> {
    await this.config.initialize();
    await this.store.initialize();
    const env = await this.config.environment.read();
    await this.store.global.set(env);
    this.authenticated = await this.store.auth.isAuthenticated();
    if (!this.authenticated) {
      this.initialized = true;
      return;
    }
    await this.afterAuth();
  }

  protected async afterAuth(): Promise<void> {
    const spacesResult = await this.store.spaces.list();
    const { items } = spacesResult;
    const [space] = items;
    if (!space) {
      return;
    }
    this.space = space;
    this.store.space = space.key;
    await this.store.observeFiles();
    this.initialized = true;
    this.render();
  }

  async handleAuthenticate(): Promise<void> {
    const { store } = this;
    await store.auth.authenticate({ updateEnvironment: true });
    this.authenticated = true;
    this.initialized = false;
    await this.afterAuth();
  }

  restoreAuth(): void {
    const data = localStorage.getItem(STORE_KEY);
    if (!data) {
      return;
    }
    try {
      const tmp = JSON.parse(data);
      if (tmp) {
        this.authorization = tmp;
      }
    } catch (e) {
      // 
    }
  }

  handleChange(e: Event): void {
    const input = e.target as Authorization;
    localStorage.setItem(STORE_KEY, JSON.stringify(this.authorization));
    console.log('Value changed', input.authorization);
  }

  handleDelete(): void {
    console.log('Requested to delete.');
  }

  async handleCertificateAdd(): Promise<void> {
    const { space, store } = this;
    if (!space) {
      return;
    }
    const cert = this.mocking.certificates.certificate();
    const file = CertificateFile.fromCertificate(cert, space.key).toJSON();
    await store.files.add(file);
    await store.media.add(file.key, cert, 'application/json');
  }

  contentTemplate(): TemplateResult {
    if (!this.initialized) {
      return html`
      <a href="./">Back</a>
      <div class="screen-loader">
        <p>Loading demo page</p>
        <progress></progress>
      </div>
      `;
    }

    return html`
    <a href="./">Back</a>
    <section class="demo-section">
      <h2 class="title-large">Data configuration</h2>
      <div class="demo-row">
        <ui-button type="outlined" @click="${this.handleCertificateAdd}">Add a certificate</ui-button>
      </div>
    </section>

    <section class="demo-section">
      <cc-authorization 
        canDelete
        canToggle
        .authorization="${this.authorization}" 
        @change="${this.handleChange}" 
        @delete="${this.handleDelete}"
      ></cc-authorization>
    </section>
    `;
  }
}

const instance = new ComponentDemoPage();
instance.initialize();
