// src/framework/shadowlisp/primitives/SlRef.ts
//
// Vision 49: Variable reference element - IS a Matrix component
//
// <sl-ref>x</sl-ref> looks up variable 'x' in the environment.
//
// As a Matrix component:
//   mount: app.ref-1
//   accepts: eval (with env parameter)
//   Callable via MCP with environment passed as parameter

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

/**
 * SlRef - Variable reference element that IS a Matrix component.
 *
 * @example
 * <sl-ref>x</sl-ref>         => value of x in environment
 * <sl-ref>counter</sl-ref>   => value of counter
 *
 * Callable via Matrix MCP:
 * mcp__matrix_call({ mount: "matrix/app.ref-1", command: "eval", params: { env: [["x", 42]] } })
 * => 42
 */
export class SlRef extends SlMatrixElement {
  /**
   * Get the variable name.
   */
  get name(): string {
    return this.textContent?.trim() ?? '';
  }

  /**
   * Set the variable name.
   */
  set name(s: string) {
    this.textContent = s;
  }

  /**
   * Look up the variable in the environment.
   * Called via Matrix transport when someone sends eval command.
   */
  async evalSelf(env: SExpr[]): Promise<SExpr> {
    // Cast to SExpr - closures are handled specially elsewhere
    return SlBootstrap.lookup(this.name, env as SlEnv) as SExpr;
  }

  /**
   * Convert to S-expression (just the symbol name).
   */
  toSExpr(): SExpr {
    return this.name;
  }
}

if (!customElements.get('sl-ref')) {
  customElements.define('sl-ref', SlRef);
}
