// src/framework/shadowlisp/primitives/SlAdd.ts
//
// Vision 49: Addition element - IS a Matrix component
//
// <sl-add mount="app.add-1"><a><b></sl-add> => a + b
//
// As a Matrix component:
//   mount: app.add-1
//   accepts: eval
//   Evaluates children and adds their values

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

/**
 * SlAdd - Addition element that IS a Matrix component.
 *
 * Adds all child values together.
 *
 * @example
 * <sl-add><sl-num>2</sl-num><sl-num>3</sl-num></sl-add>  => 5
 *
 * Callable via Matrix MCP:
 * mcp__matrix_call({ mount: "matrix/app.add-1", command: "eval" })
 * => 5
 */
export class SlAdd extends SlMatrixElement {
  /**
   * Add all child values.
   * Called via Matrix transport when someone sends eval command.
   */
  async evalSelf(env: SExpr[]): Promise<SExpr> {
    let result = 0;

    for (const child of this.children) {
      // Evaluate each child by calling its mount
      const value = await this.evalChild(child, env);

      if (typeof value !== 'number') {
        throw new Error(`sl-add: expected number, got ${typeof value}`);
      }
      result = SlBootstrap.add(result, value);
    }

    return result;
  }

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

if (!customElements.get('sl-add')) {
  customElements.define('sl-add', SlAdd);
}
