// retoor <retoor@molodetz.nl>

import { Component } from "./Component.js";
import { assetUrl } from "../assetVersion.js";

const CSS_ID = "ai-choice-css";

export class AiChoice extends Component {
  static get observedAttributes() {
    return ["name", "label", "help", "display", "required", "disabled", "value"];
  }

  constructor() {
    super();
    this._value = "";
  }

  _ensureCss() {
    if (document.getElementById(CSS_ID)) return;
    const link = document.createElement("link");
    link.id = CSS_ID;
    link.rel = "stylesheet";
    link.href = assetUrl("/static/css/components/ai-choice.css");
    document.head.appendChild(link);
  }

  connectedCallback() {
    this._ensureCss();
    if (this._built) return;
    this._built = true;
    this.classList.add("ai-choice");
    this._value = this.attr("value", "");
    const name = this.attr("name", "choice");
    const label = this.attr("label", "Choice");
    const display = this.attr("display", "auto");
    const options = [...this.querySelectorAll("ai-option")].map((el) => ({
      value: el.getAttribute("value") || "",
      label: el.getAttribute("label") || el.textContent || "",
      description: el.getAttribute("description") || "",
      disabled: el.hasAttribute("disabled"),
      selected: el.hasAttribute("selected"),
    }));
    this.innerHTML = "";
    const title = document.createElement("div");
    title.className = "ai-widget-label";
    title.textContent = label;
    this.appendChild(title);
    if (this.attr("help")) {
      const help = document.createElement("div");
      help.className = "ai-widget-help";
      help.textContent = this.attr("help");
      this.appendChild(help);
    }
    if (display === "select" || (display === "auto" && options.length > 6)) {
      const select = document.createElement("select");
      select.className = "ai-choice-select";
      select.name = name;
      const blank = document.createElement("option");
      blank.value = "";
      blank.textContent = "Select…";
      select.appendChild(blank);
      for (const option of options) {
        const el = document.createElement("option");
        el.value = option.value;
        el.textContent = option.label;
        el.disabled = option.disabled;
        if (option.selected || option.value === this._value) el.selected = true;
        select.appendChild(el);
      }
      select.addEventListener("change", () => {
        this._value = select.value;
        this._emit(name);
      });
      this.appendChild(select);
      this._value = select.value;
      return;
    }
    const group = document.createElement("div");
    group.className = "ai-choice-options";
    group.setAttribute("role", "radiogroup");
    group.setAttribute("aria-label", label);
    for (const option of options) {
      const btn = document.createElement("button");
      btn.type = "button";
      btn.className = "ai-choice-option";
      btn.disabled = option.disabled;
      btn.dataset.value = option.value;
      btn.innerHTML = `<span class="ai-choice-option-label"></span>`;
      btn.querySelector(".ai-choice-option-label").textContent = option.label;
      if (option.description) {
        const desc = document.createElement("span");
        desc.className = "ai-choice-option-desc";
        desc.textContent = option.description;
        btn.appendChild(desc);
      }
      if (option.selected || option.value === this._value) {
        btn.classList.add("selected");
        this._value = option.value;
      }
      btn.addEventListener("click", () => {
        this._value = option.value;
        group.querySelectorAll(".ai-choice-option").forEach((el) => el.classList.remove("selected"));
        btn.classList.add("selected");
        this._emit(name);
      });
      group.appendChild(btn);
    }
    this.appendChild(group);
  }

  _emit(name) {
    this.dispatchEvent(
      new CustomEvent("ai:change", {
        bubbles: true,
        composed: true,
        detail: { name, value: this._value },
      })
    );
  }

  getValue() {
    return this._value;
  }

  validate() {
    if (this.boolAttr("required") !== false && !this._value) {
      return { valid: false, message: `${this.attr("label", "Choice")} is required` };
    }
    return { valid: true };
  }
}

if (!customElements.get("ai-choice")) {
  customElements.define("ai-choice", AiChoice);
}

export default AiChoice;
