import { bindable, computedFrom, customElement, inlineView, observable, TaskQueue } from "aurelia-framework";

@customElement("ui-field")
@inlineView(`
<template aria-required.bind="required" aria-disabled.bind="disabled" class="ui-field \${classes}" css.bind="{width}">
  <slot name="title-left"></slot>
  <label title="\${label}" class="ui-field__label" role="text" click.trigger="focus()">
    <span>\${label}</span>
    <span show.bind="isRequired">*</span>
  </label>
  <span if.bind="hint" class="ui-field__hint-icon" ui-tooltip="value.one-time:hint; position.one-time:hintPosition; use-click.one-time:true">
    <ui-icon icon="digi-info-input" size="sm"></ui-icon>
  </span>
  <slot></slot>
</template>`)
export class UIField {
  @bindable()
  public label: string = "";
  @bindable()
  public plain: string | boolean = false;
  @bindable()
  public required: string | boolean = false;
  @bindable()
  public disabled: string | boolean = false;
  @bindable()
  public hint: string;
  @bindable()
  public hintPosition: string = "top";

  @bindable()
  public width: string = "auto";

  @observable
  private isEmpty = false;
  @observable
  private hasError = false;
  @observable
  private hasDisabled = false;
  @observable
  private hasReadonly = false;

  constructor(protected element: Element, private taskQueue: TaskQueue) {
    if (element.hasAttribute("nolabel")) {
      element.classList.add("ui-field--nolabel");
    }
    if (element.hasAttribute("inline")) {
      element.classList.add("ui-field--inline");
    }
    if (element.hasAttribute("label-multi-line")) {
      element.classList.add("ui-field--label-multi-line");
    }
  }

  public focus(): void {
    const el: HTMLInputElement = this.element.querySelector("input, textarea, select");
    if (el !== null && el.readOnly === false && el.disabled === false) {
      el.focus();
    }
  }

  protected attached() {
    this.taskQueue.queueMicroTask(() => {
      const el: HTMLInputElement = this.element.querySelector("input, textarea, select, ui-input, ui-select, ui-date-picker, ui-ml-input, ui-ml-textarea");
      if (el != null) {
        if (el.tagName.toLowerCase() == 'select') {
          if (el.textContent?.trim()?.length == 0 && el.parentElement?.classList.contains('ui-input--readonly')) {
            this.isEmpty = true;
          }
        } else {
          const val = el.value;
          if (val?.length == 0 && el.parentElement?.classList.contains('ui-input--readonly')) {
            this.isEmpty = true;
          }
        }
        this.hasReadonly = el.hasAttribute('readonly');
        this.hasDisabled = el.hasAttribute('disabled');
        el.addEventListener("input-invalid", () => {
          this.hasError = true;
        });
        el.addEventListener("input-valid", () => {
          this.hasError = false;
        });
        el.addEventListener("input-readonly", () => {
          this.hasReadonly = true;
        });
        el.addEventListener("input-not-readonly", () => {
          this.hasReadonly = false;
        });
        el.addEventListener("input-disabled", () => {
          this.hasDisabled = true;
        });
        el.addEventListener("input-not-disabled", () => {
          this.hasDisabled = false;
        });
      }
    });
  }

  @computedFrom("required")
  get isRequired() {
    return this.required === "" || this.required === "required" || isTrue(this.required);
  }

  @computedFrom("plain", "required", "isEmpty", 'disabled', 'hasError', 'hasReadonly', 'hasDisabled')
  get classes(): string {
    const classes = [];
    if (this.plain === "" || this.plain === "plain" || isTrue(this.plain)) {
      classes.push("ui-field--plain");
    }
    if (this.isRequired) {
      classes.push("ui-field--required");
    }
    if (this.isEmpty === true) {
      classes.push("ui-field--empty");
    }
    if (this.disabled || this.hasDisabled) {
      classes.push("ui-field--disabled");
    }
    if (this.hasError) {
      classes.push("ui-field--invalid");
    }
    if (this.hasReadonly) {
      classes.push("ui-field--readonly");
    }
    if (this.hint) {
      classes.push("ui-field--hint");
    }
    return classes.join(" ");
  }
}
