/**
 * arcrun WASM 零件 Worker (claude_api v2)
 * POST / → JSON input → WASM (WASI preview1) → JSON output
 * SDD: polaris/mira/.agents/specs/mira-app/design.md §6
 *
 * v2 改打 Mira daemon (Hetzner) 而非直打 Anthropic Messages API
 * 理由：OAuth token 在 Messages API 限制 system prompt → rate_limit
 *       Mira daemon 用 Claude Agent SDK，已內建 Mira persona
 */

import componentWasm from '../component.wasm' assert { type: 'webassembly' };
import { Hono } from 'hono';
import { cors } from 'hono/cors';
import { createWasiShim, type WasiHostFunctions } from '../../../cypher-executor/src/lib/wasi-shim';

type Env = {
  MIRA_TOKEN?: string;     // Mira daemon Bearer token
  MIRA_URL?: string;        // 預設 https://mira.uncle6.me
  COMPONENT_ID: string;
};

const app = new Hono<{ Bindings: Env }>();
app.use('*', cors());

app.get('/', (c) => c.json({ ok: true, component: 'claude_api', version: 'v2-mira-daemon' }));

app.post('/', async (c) => {
  let input: Record<string, unknown>;
  try {
    input = await c.req.json();
  } catch {
    return c.json({ success: false, error: 'request body must be JSON' }, 400);
  }

  // 用戶沒帶 token → 用 Worker secret fallback
  if (!input.mira_token && c.env.MIRA_TOKEN) {
    input.mira_token = c.env.MIRA_TOKEN;
  }
  if (!input.mira_url && c.env.MIRA_URL) {
    input.mira_url = c.env.MIRA_URL;
  }

  try {
    const result = await runWasm(input);
    return c.json(result);
  } catch (e) {
    return c.json(
      { success: false, error: e instanceof Error ? e.message : String(e) },
      500,
    );
  }
});

export default app;

async function runWasm(input: unknown): Promise<unknown> {
  const hostFunctions: WasiHostFunctions = {
    http_request: async (url, method, headersJson, body) => {
      const headers: Record<string, string> = {};
      if (headersJson) {
        try {
          const parsed = JSON.parse(headersJson);
          if (parsed && typeof parsed === 'object') {
            for (const [k, v] of Object.entries(parsed as Record<string, unknown>)) {
              if (typeof v === 'string') headers[k] = v;
            }
          }
        } catch {}
      }
      const init: RequestInit = { method, headers };
      if (body && method.toUpperCase() !== 'GET' && method.toUpperCase() !== 'HEAD') {
        init.body = body;
      }
      const res = await fetch(url, init);
      const text = await res.text();
      // 修架構債（同 http_request）：非 2xx 包成帶 "error" key 的 envelope，
      // 讓 WASM 端既有的 error 判定正確識別失敗（原本只回 body 丟掉 status → 4xx 被判 success）。
      if (!res.ok) {
        return JSON.stringify({ error: `HTTP ${res.status}`, status: res.status, body: text });
      }
      return text;
    },
  };

  const shim = createWasiShim(JSON.stringify(input), hostFunctions);
  const instance = await WebAssembly.instantiate(
    componentWasm as WebAssembly.Module,
    shim.imports,
  );
  shim.setMemory(instance.exports.memory as WebAssembly.Memory);
  await shim.run(instance);

  const stdout = shim.getStdout().trim();
  const stderr = shim.getStderr().trim();
  if (stderr) console.error('[claude_api wasm stderr]', stderr);
  if (!stdout) throw new Error('WASM component produced no output');
  return JSON.parse(stdout);
}
