// src/framework/shadowlisp/primitives/SlSub.ts
//
// Vision 49: Subtraction element - IS a Matrix component
//
// <sl-sub><a><b></sl-sub> => a - b

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

/**
 * SlSub - Subtraction element that IS a Matrix component.
 *
 * @example
 * <sl-sub><sl-num>5</sl-num><sl-num>3</sl-num></sl-sub>  => 2
 */
export class SlSub extends SlMatrixElement {
  async evalSelf(env: SExpr[]): Promise<SExpr> {
    const children = Array.from(this.children);
    if (children.length === 0) return 0;

    // Evaluate first operand
    const result = await this.evalChild(children[0], env) as number;

    // If only one operand, negate it
    if (children.length === 1) {
      return -result;
    }

    // Subtract remaining operands
    let acc = result;
    for (let i = 1; i < children.length; i++) {
      const value = await this.evalChild(children[i], env);
      if (typeof value !== 'number') {
        throw new Error(`sl-sub: expected number, got ${typeof value}`);
      }
      acc = SlBootstrap.sub(acc, value);
    }

    return acc;
  }

  toSExpr(): SExpr {
    const args = Array.from(this.children).map(c =>
      (c instanceof SlMatrixElement) ? c.toSExpr() : null
    );
    return ['-', ...args];
  }
}

if (!customElements.get('sl-sub')) {
  customElements.define('sl-sub', SlSub);
}
