// retoor <retoor@molodetz.nl>

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

const CSS_ID = "ai-choice-multi-css";

export class AiChoiceMulti extends Component {
  static get observedAttributes() {
    return ["name", "label", "help", "required", "disabled", "min-selected", "max-selected"];
  }

  constructor() {
    super();
    this._values = new Set();
  }

  _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-multi");
    const name = this.attr("name", "choices");
    const label = this.attr("label", "Choices");
    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);
    }
    const group = document.createElement("div");
    group.className = "ai-choice-options multi";
    for (const option of options) {
      const labelEl = document.createElement("label");
      labelEl.className = "ai-choice-check";
      const input = document.createElement("input");
      input.type = "checkbox";
      input.value = option.value;
      input.disabled = option.disabled;
      if (option.selected) {
        input.checked = true;
        this._values.add(option.value);
      }
      input.addEventListener("change", () => {
        if (input.checked) this._values.add(option.value);
        else this._values.delete(option.value);
        this.dispatchEvent(
          new CustomEvent("ai:change", {
            bubbles: true,
            composed: true,
            detail: { name, value: this.getValue() },
          })
        );
      });
      const span = document.createElement("span");
      span.textContent = option.label;
      labelEl.append(input, span);
      if (option.description) {
        const desc = document.createElement("small");
        desc.textContent = option.description;
        labelEl.appendChild(desc);
      }
      group.appendChild(labelEl);
    }
    this.appendChild(group);
  }

  getValue() {
    return [...this._values];
  }

  validate() {
    const min = this.intAttr("min-selected", this.boolAttr("required") ? 1 : 0);
    const max = this.intAttr("max-selected", 0);
    const count = this._values.size;
    if (count < min) {
      return { valid: false, message: `${this.attr("label", "Choices")}: select at least ${min}` };
    }
    if (max > 0 && count > max) {
      return { valid: false, message: `${this.attr("label", "Choices")}: select at most ${max}` };
    }
    return { valid: true };
  }
}

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

export default AiChoiceMulti;
