import { html, TemplateResult } from 'lit';
import { AmfDemoPage } from './lib/AmfDemoPage.js';
import { reactive } from '../../src/lib/decorators.js';
import { AmfTypes, ApiNavigationEvent, ServerChangeEvent, ServerCountChangeEvent } from '../../src/index.js';
import CheckboxElement from '../../src/ui/input/CheckboxElement.js';
import '../../src/define/amf/api-server-picker.js';
import '../../src/define/amf/api-navigation.js';
import '../../src/define/ui/ui-checkbox.js';
import '../../src/define/ui/ui-list-item.js';

interface IDemoState {
  extraServers?: boolean;
  customUri?: boolean;
  autoSelect?: boolean;
  serverValue?: string;
}

const stateKey = 'DtJMGcAkHi';

class ComponentDemo extends AmfDemoPage {
  @reactive() domainId?: string;

  @reactive() domainType?: AmfTypes.SelectionType;

  /**
   * When set it adds extra `<ui-list-item>`s with custom servers definition.
   */
  @reactive() extraServers: boolean;

  /**
   * When set it sets the `custom` property which allows rendering of the "Enter custom URL"
   * option.
   */
  @reactive() customUri: boolean;

  @reactive() autoSelect: boolean;

  @reactive() serversCount?: number;

  @reactive() selectedType?: string;

  @reactive() serverValue?: string;

  @reactive() baseUri?: string;

  state: IDemoState;

  constructor() {
    super();

    this.componentName = 'api-server-picker';
    this.extraServers = false;
    this.customUri = false;
    this.autoSelect = false;
    this.state = {};

    this.apis = [
      {
        file: 'models/servers-api.json',
        label: 'Servers API',
      },
      {
        file: 'models/no-servers-api.json',
        label: 'No Servers API',
      },
    ];

    this._restoreState();
    this.autoLoad();
  }

  _restoreState(): void {
    const raw = localStorage.getItem(stateKey);
    if (!raw) {
      return;
    }
    const parsed = JSON.parse(raw) as IDemoState;
    this.state = parsed;
    if (typeof parsed.autoSelect === 'boolean') {
      this.autoSelect = parsed.autoSelect;
    }
    if (typeof parsed.customUri === 'boolean') {
      this.customUri = parsed.customUri;
    }
    if (typeof parsed.extraServers === 'boolean') {
      this.extraServers = parsed.extraServers;
    }
    if (parsed.serverValue) {
      this.serverValue = parsed.serverValue;
    }
  }

  _storeState(): void {
    const raw = JSON.stringify(this.state);
    localStorage.setItem(stateKey, raw);
  }

  _navChanged(e: ApiNavigationEvent): void {
    const { domainId, domainType } = e.detail;
    if (["operation", "resource"].indexOf(domainType) === -1) {
      return;
    }
    this.domainId = domainId;
    this.domainType = domainType;
  }

  _apiSrvHandler(e: ServerChangeEvent): void {
    const { value, type } = e.detail;
    this.serverValue = value;
    this.selectedType = type;
    this.state.serverValue = value;
    this._storeState();
    console.log("Selection changed", value, type);
  }

  _countHandler(e: ServerCountChangeEvent): void {
    this.serversCount = e.detail.value;
    console.log("Server count", e.detail.value);
  }

  protected _toggleBooleanOption(e: Event): void {
    super._toggleBooleanOption(e);
    const { name, checked } = e.target as CheckboxElement;
    this.state[name as keyof Pick<IDemoState, 'autoSelect' | 'customUri' | 'extraServers'>] = checked;
    this._storeState();
  }

  protected _baseUriHandler(e: Event): void {
    const input = e.target as HTMLInputElement;
    this.baseUri = input.value;
  }

  contentTemplate(): TemplateResult {
    const { loaded } = this;
    if (!loaded) {
      return html`<a href="./">Back</a><p>Load an API model first.</p>`;
    }
    const {
      customUri,
      serverValue,
      serversCount,
      autoSelect,
      domainId,
      domainType,
      extraServers,
      selectedType,
      baseUri,
    } = this;
    return html`
    <a href="./">Back</a>
    <section class="demo-section">
      <api-server-picker
        ?custom="${customUri}"
        ?auto="${autoSelect}"
        .domainId="${domainId}"
        .domainType="${domainType}"
        .value="${serverValue}"
        .baseUri="${baseUri}"
        @apiserverchanged="${this._apiSrvHandler}"
        @serverscountchanged="${this._countHandler}"
      >
        ${this._extraSlotItems()}
      </api-server-picker>
    </section>

    <hr/>

    <section class="demo-section">
      <p class="block" id="mainOptionsLabel">Options</p>

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

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

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

      <div>
        <label for="baseUriValue">Base URI</label>
        <input type="url" id="baseUriValue" aria-describedby="baseUriDesc" @change="${this._baseUriHandler}"/>
        <p id="baseUriDesc">Enter a value to set on the picker as the <code>baseUri</code> property.</p>
      </div>
    </section>

    <hr/>

    ${serverValue ? html`<p>Selected value: ${serverValue}</p>` : ""}
    ${serverValue ? html`<p>Selected type: ${selectedType}</p>` : ""}
    ${serversCount ? html`<p>Servers count: ${serversCount}</p>` : ""}
    `;
  }

  _extraSlotItems(): TemplateResult | string {
    if (!this.extraServers) {
      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/v1/">Mocking service</ui-list-item>
    <ui-list-item slot="custom-base-uri" data-value="http://instance.com">Custom instance</ui-list-item>
    <ui-list-item slot="custom-base-uri">Unselectable</ui-list-item>
    `;
  }
}

const instance = new ComponentDemo();
instance.render();
