/**
 * Non-side-effect class export for `<pipeline-status-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/pipeline-status`
 * (which imports this file + calls `defineIfFree()`).
 *
 * @see ../../USAGE.md#registration--auto-vs-explicit
 */

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

/**
 * <pipeline-status-ui> — Single updating pipeline status indicator.
 *
 * Shows the current stage with a message. Completed stages collapse into
 * an expandable history log. Auto-collapses when the pipeline finishes.
 *
 * Properties:
 *   stage   : String — current stage name (interpret, analyze, plan, generate, validate, render)
 *   message : String — current stage description
 *   status  : String — 'idle' | 'active' | 'completed' | 'error'. Set to
 *                       'completed' to render the final state and collapse
 *                       the history log.
 */

const STAGE_LABELS = {
  interpret: 'Interpreting',
  analyze: 'Analyzing',
  plan: 'Planning',
  generate: 'Generating',
  validate: 'Validating',
  render: 'Rendering',
};

export class UIPipelineStatus extends UIElement {
  static properties = {
    stage:   { type: String, default: '', reflect: true },
    message: { type: String, default: '', reflect: true },
    // `status` is the canonical stage-progress shape (matches timeline-item-ui,
    // stepper-item-ui, agent-reasoning-ui).
    status:  { type: String, default: 'idle', reflect: true },
  };

  static template = () => null;

  #history = [];
  #bound = false;
  #containerEl = null;
  #currentEl = null;
  #dotEl = null;
  #labelEl = null;
  #msgEl = null;
  #detailsEl = null;
  #summaryEl = null;
  #logEl = null;
  #prevStage = '';
  #prevMessage = '';

  connected() {
    this.setAttribute('role', 'status');
    this.setAttribute('aria-label', 'Pipeline status');
  }

  render() {
    if (!this.#bound) {
      this.#bound = true;
      this.#buildDOM();
    }

    this.#update();
  }

  #buildDOM() {
    this.#containerEl = document.createElement('div');
    this.#containerEl.setAttribute('data-pipeline-status', '');

    // Current stage row
    this.#currentEl = document.createElement('div');
    this.#currentEl.setAttribute('data-pipeline-current', '');

    this.#dotEl = document.createElement('span');
    this.#dotEl.setAttribute('data-pipeline-dot', '');

    this.#labelEl = document.createElement('span');
    this.#labelEl.setAttribute('data-pipeline-label', '');

    this.#msgEl = document.createElement('span');
    this.#msgEl.setAttribute('data-pipeline-msg', '');

    this.#currentEl.append(this.#dotEl, this.#labelEl, this.#msgEl);

    // History (expandable)
    this.#detailsEl = document.createElement('details');
    this.#detailsEl.setAttribute('data-pipeline-history', '');
    this.#detailsEl.hidden = true;

    this.#summaryEl = document.createElement('summary');
    this.#detailsEl.appendChild(this.#summaryEl);

    this.#logEl = document.createElement('ol');
    this.#logEl.setAttribute('data-pipeline-log', '');
    this.#detailsEl.appendChild(this.#logEl);

    this.#containerEl.append(this.#currentEl, this.#detailsEl);
    this.appendChild(this.#containerEl);
  }

  #update() {
    const { stage, message } = this;

    if (this.status === 'completed') {
      // Move current to history if not already
      if (this.#prevStage && this.#prevStage !== this.#history[this.#history.length - 1]?.stage) {
        this.#pushHistory(this.#prevStage, this.#prevMessage);
      }
      // Final state
      this.#dotEl.setAttribute('data-pipeline-dot', 'complete');
      this.#labelEl.textContent = 'Complete';
      this.#msgEl.textContent = '';
      this.#updateHistoryUI();
      return;
    }

    // Stage transition: push previous to history
    if (stage && stage !== this.#prevStage && this.#prevStage) {
      this.#pushHistory(this.#prevStage, this.#prevMessage);
    }

    // Update current
    const label = STAGE_LABELS[stage] || stage;
    this.#dotEl.setAttribute('data-pipeline-dot', 'active');
    this.#dotEl.setAttribute('data-stage', stage);
    this.#labelEl.textContent = label;
    this.#msgEl.textContent = message ? `— ${message}` : '';

    this.#prevStage = stage;
    this.#prevMessage = message;

    this.#updateHistoryUI();
  }

  #pushHistory(stage, message) {
    this.#history.push({ stage, message, timestamp: Date.now() });
  }

  #updateHistoryUI() {
    if (this.#history.length === 0) {
      this.#detailsEl.hidden = true;
      return;
    }

    this.#detailsEl.hidden = false;
    this.#summaryEl.textContent = `${this.#history.length} step${this.#history.length > 1 ? 's' : ''} completed`;

    // Rebuild log
    this.#logEl.innerHTML = '';
    for (const entry of this.#history) {
      const li = document.createElement('li');
      const dot = document.createElement('span');
      dot.setAttribute('data-pipeline-dot', 'complete');
      const text = document.createElement('span');
      const label = STAGE_LABELS[entry.stage] || entry.stage;
      text.textContent = entry.message ? `${label} — ${entry.message}` : label;
      li.append(dot, text);
      this.#logEl.appendChild(li);
    }

    // Auto-close when complete
    if (this.status === 'completed') {
      this.#detailsEl.removeAttribute('open');
    }
  }

  disconnected() {
    this.#containerEl = null;
    this.#currentEl = null;
    this.#dotEl = null;
    this.#labelEl = null;
    this.#msgEl = null;
    this.#detailsEl = null;
    this.#summaryEl = null;
    this.#logEl = null;
    this.#bound = false;
  }
}
