/**
 * Layer 5: Compute (Server) — Server-side transform runner.
 *
 * Handles POST /:space/api/compute/:transformId requests from clients
 * that can't run a transform locally (e.g. PDF generation, image thumbnailing).
 *
 * Usage in server/index.ts:
 *   import { createComputeRouter, registerServerTransform } from './local-first/compute-server';
 *   const computeRouter = createComputeRouter();
 *   app.route('/:space/api/compute', computeRouter);
 */

import { Hono } from 'hono';

// ============================================================================
// TYPES
// ============================================================================

export interface ServerTransform<In = unknown, Out = unknown> {
  id: string;
  /** Execute the transform on the server */
  execute(input: In, context: TransformContext): Promise<Out>;
}

export interface TransformContext {
  space: string;
  /** Auth claims from EncryptID JWT (null if unauthenticated) */
  claims: Record<string, unknown> | null;
}

// ============================================================================
// REGISTRY
// ============================================================================

const transforms = new Map<string, ServerTransform<any, any>>();

export function registerServerTransform<In, Out>(transform: ServerTransform<In, Out>): void {
  transforms.set(transform.id, transform);
}

export function getServerTransform(id: string): ServerTransform | undefined {
  return transforms.get(id);
}

// ============================================================================
// HONO ROUTER
// ============================================================================

/**
 * Create a Hono router that handles compute requests.
 * Mount at /:space/api/compute
 */
export function createComputeRouter(): Hono {
  const router = new Hono();

  // List available transforms
  router.get('/', (c) => {
    const list = Array.from(transforms.keys());
    return c.json({ transforms: list });
  });

  // Execute a transform
  router.post('/:transformId', async (c) => {
    const transformId = c.req.param('transformId');
    const transform = transforms.get(transformId);

    if (!transform) {
      return c.json({ error: `Transform "${transformId}" not found` }, 404);
    }

    try {
      const body = await c.req.json();
      const input = body.input;

      const context: TransformContext = {
        space: c.req.param('space') || 'demo',
        claims: (c as any).get?.('claims') ?? null,
      };

      const output = await transform.execute(input, context);
      return c.json({ output });
    } catch (e) {
      const message = e instanceof Error ? e.message : 'Transform execution failed';
      console.error(`[ComputeServer] Transform "${transformId}" failed:`, e);
      return c.json({ error: message }, 500);
    }
  });

  return router;
}
