import { DataAssociation, DataNamespace, EventUtils } from "@api-client/core/build/browser.js";
import { css, CSSResult, html, PropertyValues, TemplateResult } from "lit";
import { property, state } from "lit/decorators.js";
import { live } from "lit/directives/live.js";
import ApiElement from "../ApiElement.js";
import EditorCommon from './CommonStyles.js';
import theme from '../theme.js';
import typography from "../../styles/m3/typography.module.js";
import type Input from "../../ui/input/Input.js";
import type CheckboxElement from "../../ui/input/CheckboxElement.js";
import '../../define/ui/ui-text-field.js';
import '../../define/ui/ui-checkbox.js';
import '../../define/ui/ui-divider.js';
import '../../define/ui/ui-icon-button.js';
import '../../define/ui/ui-icon.js';

export default class AssociationFormElement extends ApiElement {
  static override get styles(): CSSResult[] {
    return [
      theme,
      EditorCommon,
      typography,
      css`
      :host {
        display: block;
      }
      `
    ]
  }
  
  /**
   * The key of the association to edit.
   * @attribute
   */
  @property({ type: String, reflect: true }) key?: string;

  /**
   * The read data namespace.
   */
  @property({ type: Object }) root?: DataNamespace;

  /**
   * The computed entity when the key or root change.
   */
  @state() protected _association?: DataAssociation;

  override willUpdate(cp: PropertyValues<this>): void {
    if (cp.has('key')) {
      this._computeAssociation();
    }
  }

  /**
   * Computes the view value for the association.
   * This should be called before the update is complete so this won't trigger another update.
   */
  protected _computeAssociation(): void {
    const { root, key } = this;
    if (!root || !key) {
      this._association = undefined;
      return;
    }
    this._association = root.definitions.associations.find(i => i.key === key);
  }

  protected _infoChangeHandler(e: Event): void {
    const { _association } = this;
    if (!_association) {
      return;
    }
    const node = e.target as Input;
    const { name, value } = node;
    if (!['name', 'description', 'displayName'].includes(name as string)) {
      return;
    }
    if (name === 'name' && !value) {
      return;
    }
    _association.info[name as 'name' | 'description' | 'displayName'] = value;
    this.notifyChange();
    this.requestUpdate();
  }

  protected _checkedHandler(e: Event): void {
    const { _association } = this;
    if (!_association) {
      return;
    }
    const input = e.target as CheckboxElement;
    const name = input.name as 'multiple' | 'required';
    const { checked } = input;
    if (_association[name] === checked) {
      return;
    }
    _association[name] = checked;
    this.notifyChange();
    this.requestUpdate();
  }

  protected override render(): TemplateResult {
    const { _association: item } = this;
    if (!item) {
      return html``;
    }
    const { info, multiple = false, required = false } = item;
    return html`
    <form name="data-association" @submit="${EventUtils.cancelEvent}" data-key="${item.key}">
      <ui-text-field class="input" name="name" .value="${live(info.name || '')}" label="Association name" required @change="${this._infoChangeHandler}"></ui-text-field>
      <ui-text-field class="input" name="displayName" .value="${live(info.displayName || '')}" label="Display name (optional)" @change="${this._infoChangeHandler}"></ui-text-field>
      <ui-text-field class="input" name="description" .value="${live(info.description || '')}" label="Association description (optional)" @change="${this._infoChangeHandler}"></ui-text-field>

      <div class="checkbox-group">
        <label class="label-large">
          <ui-checkbox name="required" .checked="${required}" title="Whether the association is required in the schema" @change="${this._checkedHandler}"></ui-checkbox>
          Required
        </label>
        <label class="label-large">
          <ui-checkbox name="multiple" .checked="${multiple}" title="When set it declares this association as an array. Multiple instances of the value are permitted." @change="${this._checkedHandler}"></ui-checkbox>
          Multiple
        </label>
      </div>
    </form>
    `;
  }
}
