// src/framework/shadowlisp/primitives/ISlEvaluable.ts
//
// Vision 49: Interface for evaluable ShadowLisp elements
//
// Every ShadowLisp element that can be evaluated implements this interface.

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

type SlEvaluableElementBase = HTMLElement;

/**
 * Evaluation context passed to elements during evaluation.
 */
export interface ISlEvalContext {
  /** The current environment (variable bindings) */
  env: SlEnv;

  /** Reference to the runtime for global operations */
  runtime: HTMLElement;

  /** Evaluate a child element or S-expression */
  evaluate(expr: SExpr | HTMLElement, env?: SlEnv): Promise<SExpr>;
}

/**
 * Interface for ShadowLisp elements that can be evaluated.
 *
 * Every <sl-*> element that participates in evaluation implements this.
 */
export interface ISlEvaluable extends SlEvaluableElementBase {
  /**
   * Evaluate this element in the given context.
   *
   * @param ctx - The evaluation context (env, runtime, evaluate function)
   * @returns The result of evaluation
   */
  slEval(ctx: ISlEvalContext): Promise<SExpr>;

  /**
   * Convert this element to an S-expression representation.
   */
  toSExpr(): SExpr;
}

/**
 * Type guard to check if an element is evaluable.
 */
export function isSlEvaluable(el: unknown): el is ISlEvaluable {
  return (
    el instanceof HTMLElement &&
    typeof (el as ISlEvaluable).slEval === 'function'
  );
}
