// src/framework/shadowlisp/primitives/SlClause.ts
//
// Vision 49: Clause element for cond - IS a Matrix component
//
// <sl-clause><test><result></sl-clause>

import type { SExpr } from '../../../lisp/SExpr';
import { SlMatrixElement } from '../SlMatrixElement';

/**
 * SlClause - Clause element for use inside sl-cond that IS a Matrix component.
 *
 * Contains a test and a result. If the test is true, the result is returned.
 *
 * @example
 * <sl-clause>
 *   <sl-eq><sl-ref>x</sl-ref><sl-num>0</sl-num></sl-eq>
 *   <sl-str>zero</sl-str>
 * </sl-clause>
 */
export class SlClause extends SlMatrixElement {
  /**
   * Get the test element.
   */
  get test(): Element | null {
    return this.children[0] ?? null;
  }

  /**
   * Get the result element.
   */
  get resultEl(): Element | null {
    return this.children[1] ?? null;
  }

  /**
   * Clauses don't evaluate on their own - sl-cond handles them.
   */
  async evalSelf(_env: SExpr[]): Promise<SExpr> {
    throw new Error('sl-clause cannot be evaluated directly; use inside sl-cond');
  }

  toSExpr(): SExpr {
    const test = this.test;
    const result = this.resultEl;
    return [
      (test instanceof SlMatrixElement) ? test.toSExpr() : null,
      (result instanceof SlMatrixElement) ? result.toSExpr() : null,
    ];
  }
}

if (!customElements.get('sl-clause')) {
  customElements.define('sl-clause', SlClause);
}
