import { execFile } from "node:child_process";
import { promisify } from "node:util";
import { readFile, readdir } from "node:fs/promises";
import { createRequire } from "node:module";
const APP_DIR = process.env.PROOF_CHECKOUT!;

// Synthetic fixtures go through the running server's RPC, never database writes.
export async function seedSchedules(home: string) {
  const { stdout } = await promisify(execFile)(process.execPath, [
    "apps/server/src/bin.ts", "auth", "session", "issue", "--token-only", "--ttl", "30m", "--base-dir", home,
  ], { cwd: APP_DIR });
  const runtime = JSON.parse(await readFile(`${home}/userdata/server-runtime.json`, "utf8"));
  const wsPackage = (await readdir(`${APP_DIR}/node_modules/.pnpm`)).find(p => p.startsWith("ws@8."));
  const WebSocket = createRequire(import.meta.url)(`${APP_DIR}/node_modules/.pnpm/${wsPackage}/node_modules/ws`);
  const socket = new WebSocket(`${runtime.origin.replace("http", "ws")}/ws?orchestrationProtocol=2`, { headers: { Authorization: `Bearer ${stdout.trim()}` } });
  await new Promise<void>((resolve, reject) => { socket.once("open", resolve); socket.once("error", reject); });
  let sequence = 0;
  const call = (tag: string, payload: unknown, stream = false) => new Promise<any>((resolve, reject) => {
    const id = String(++sequence);
    const listener = (raw: Buffer) => {
      const frames = JSON.parse(raw.toString());
      for (const frame of Array.isArray(frames) ? frames : [frames]) {
        if (frame.requestId !== id) continue;
        if (frame._tag === "Chunk") {
          socket.send(JSON.stringify({ _tag: "Ack", requestId: id }));
          if (stream) { socket.off("message", listener); resolve(frame.values[0]); }
        }
        if (frame._tag === "Exit") {
          socket.off("message", listener);
          if (frame.exit._tag === "Success") resolve(frame.exit.value);
          else reject(new Error(JSON.stringify(frame.exit)));
        }
      }
    };
    socket.on("message", listener);
    socket.send(JSON.stringify({ _tag: "Request", id, tag, payload, headers: [] }));
  });
  try {
    const shell = await call("orchestration.subscribeShell", {}, true);
    const project = shell.snapshot.projects.find((p: any) => p.title === "Schedule demo");
    const thread = shell.snapshot.threads.find((t: any) => t.title === "Daily report");
    const common = { prompt: "Prepare a daily summary.", projectId: project.id, threadId: thread.id, threadMode: "continue", workspaceStrategy: { type: "root" }, modelSelection: { instanceId: "devReplay", model: "multi-turn" }, runtimeMode: "full-access", interactionMode: "default" };
    const tasks = [];
    for (const [title, enabled, schedule] of [
      ["Daily report task", false, { type: "fixed_time", timeOfDay: "16:31" }],
      ["Enabled daily report", true, { type: "fixed_time", timeOfDay: "16:31" }],
      ["Interval check", false, { type: "interval", everyMs: 900000 }],
      ["Webhook check", false, { type: "webhook" }],
    ] as const) tasks.push(await call("scheduledTasks.upsert", { ...common, title, enabled, schedule }));
    return tasks;
  } finally { socket.close(); }
}
