/**
 * Non-side-effect class export for `<agent-questions-ui>`.
 *
 * Importing this file gives you the class(es) without auto-registering the tag.
 * Useful for test isolation, subclassing with tag-name override, or selective
 * composition.
 *
 * The auto-register path stays at `@adia-ai/web-components/components/agent-questions`
 * (which imports this file + calls `defineIfFree()`).
 *
 * @see ../../USAGE.md#registration--auto-vs-explicit
 */

/**
 * <agent-questions-ui> — Multi-choice clarifying-question cards.
 *
 * The agent asks a structured question and offers 2-6 options as stacked cards
 * (claude.ai style). Supports single- or multi-select. On submit, host receives
 * the picked option ids.
 *
 * JS API:
 *   el.question = 'Which direction fits best?';
 *   el.helper   = 'Pick one — we can revisit later.';
 *   el.options  = [
 *     { id: 'lean',      label: 'Lean & minimal',   description: 'Whitespace-heavy, neutral palette.', icon: 'square' },
 *     { id: 'expressive',label: 'Expressive',       description: 'Bold type, vivid accents.',         icon: 'sparkle' },
 *     { id: 'utilitarian',label: 'Utilitarian',     description: 'Dense, information-first.',          icon: 'gear' },
 *   ];
 *
 *   el.addEventListener('questions-answer', (e) => {
 *     // detail: { selected: string[], option: optionObject | null }
 *   });
 *
 * Attributes:
 *   multi      — allow multiple selections (default: false)
 *   submit-label — label for the submit button (shown only when multi)
 *
 * Events:
 *   questions-answer — detail: { selected: string[], option: chosen | null }
 */

import { UIElement } from '../../core/element.js';

function escapeText(s) {
  return String(s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
}

function escapeAttr(s) {
  return String(s).replace(/"/g, '&quot;');
}

export class UIAgentQuestions extends UIElement {
  // §154 (v0.5.3): Phosphor icons this primitive auto-stamps (without
  // consumer markup). Aggregated by installIconLoadersForRegistered()
  // across all defined elements. Audited by check-required-icons.mjs
  // (slot 11). Per FEEDBACK-06 §4 + FEEDBACK-07 §4.
  static requiredIcons = ['check'];

  static properties = {
    multi:       { type: Boolean, default: false, reflect: true },
    question:    { type: String,  default: '',    reflect: true },
    helper:      { type: String,  default: '',    reflect: true },
    submitLabel: { type: String,  default: 'Continue', reflect: true, attribute: 'submit-label' },
  };

  static template = () => null;

  #options = [];
  #selected = new Set();
  #answered = false;
  #questionEl = null;
  #helperEl = null;
  #optionsEl = null;
  #submitEl = null;

  get options() { return this.#options; }
  set options(v) {
    this.#options = Array.isArray(v) ? v.slice() : [];
    this.#selected.clear();
    this.#answered = false;
    this.#render();
  }

  connected() {
    this.#build();
  }

  disconnected() {
    this.#submitEl?.removeEventListener('press', this.#onSubmit);
    this.#questionEl = this.#helperEl = this.#optionsEl = this.#submitEl = null;
  }

  render() {
    // Keep question/helper text in sync with attribute changes
    if (this.#questionEl) {
      this.#questionEl.textContent = this.question || '';
      this.#questionEl.hidden = !this.question;
    }
    if (this.#helperEl) {
      this.#helperEl.textContent = this.helper || '';
      this.#helperEl.hidden = !this.helper;
    }
    if (this.#submitEl) {
      this.#submitEl.setAttribute('text', this.submitLabel || 'Continue');
      this.#submitEl.hidden = !this.multi;
    }
  }

  #build() {
    this.innerHTML = '';

    this.#questionEl = document.createElement('div');
    this.#questionEl.setAttribute('data-questions-q', '');
    if (this.question) this.#questionEl.textContent = this.question;
    else this.#questionEl.hidden = true;

    this.#helperEl = document.createElement('div');
    this.#helperEl.setAttribute('data-questions-helper', '');
    if (this.helper) this.#helperEl.textContent = this.helper;
    else this.#helperEl.hidden = true;

    this.#optionsEl = document.createElement('div');
    this.#optionsEl.setAttribute('data-questions-options', '');

    this.#submitEl = document.createElement('button-ui');
    this.#submitEl.setAttribute('text', this.submitLabel || 'Continue');
    this.#submitEl.setAttribute('variant', 'primary');
    this.#submitEl.setAttribute('size', 'sm');
    this.#submitEl.setAttribute('disabled', '');
    if (!this.multi) this.#submitEl.hidden = true;
    this.#submitEl.addEventListener('press', this.#onSubmit);

    this.append(this.#questionEl, this.#helperEl, this.#optionsEl, this.#submitEl);
    this.#render();
  }

  #render() {
    if (!this.#optionsEl) return;
    this.#optionsEl.innerHTML = '';

    for (const opt of this.#options) {
      const card = document.createElement('button');
      card.type = 'button';
      card.setAttribute('data-questions-option', '');
      card.setAttribute('role', this.multi ? 'checkbox' : 'radio');
      card.setAttribute('aria-checked', this.#selected.has(opt.id) ? 'true' : 'false');
      if (this.#selected.has(opt.id)) card.setAttribute('data-selected', '');
      if (this.#answered) card.setAttribute('disabled', '');

      const iconHTML = opt.icon
        ? `<icon-ui name="${escapeAttr(opt.icon)}" color="muted" data-questions-option-icon></icon-ui>`
        : '';
      const checkHTML = `
        <span data-questions-option-check aria-hidden="true">
          <icon-ui name="check" size="sm" color="accent"></icon-ui>
        </span>`;

      card.innerHTML = `
        ${iconHTML}
        <span data-questions-option-body>
          <span data-questions-option-label>${escapeText(opt.label || '')}</span>
          ${opt.description ? `<span data-questions-option-desc>${escapeText(opt.description)}</span>` : ''}
        </span>
        ${checkHTML}
      `;

      card.addEventListener('click', () => this.#pick(opt));
      this.#optionsEl.appendChild(card);
    }

    if (this.#submitEl) {
      this.#submitEl.disabled = this.#answered || this.#selected.size === 0;
    }
  }

  #pick(opt) {
    if (this.#answered) return;
    if (this.multi) {
      if (this.#selected.has(opt.id)) this.#selected.delete(opt.id);
      else this.#selected.add(opt.id);
      this.#render();
    } else {
      this.#selected.clear();
      this.#selected.add(opt.id);
      this.#answered = true;
      this.#render();
      this.dispatchEvent(new CustomEvent('questions-answer', {
        bubbles: true,
        detail: { selected: [opt.id], option: opt },
      }));
    }
  }

  #onSubmit = () => {
    if (this.#answered || this.#selected.size === 0) return;
    this.#answered = true;
    this.#render();
    const ids = [...this.#selected];
    const first = this.#options.find(o => o.id === ids[0]) || null;
    this.dispatchEvent(new CustomEvent('questions-answer', {
      bubbles: true,
      detail: { selected: ids, option: first },
    }));
  };
}
