import { readFile } from "node:fs/promises";
import { privateKeyToAccount } from "viem/accounts";
import { z } from "zod";
import {
  eventSigningMessage,
  unsignedAgentEventSchema,
  type SignedAgentEvent,
} from "@pons-agent/protocol";

const environmentSchema = z.object({
  AGENT_ID: z.string().min(3),
  AGENT_EVENT_ENDPOINT: z.string().url(),
  EVM_PRIVATE_KEY: z.string().regex(/^0x[a-fA-F0-9]{64}$/),
});

const getArgument = (name: string) => {
  const index = process.argv.indexOf(name);
  return index === -1 ? undefined : process.argv[index + 1];
};

const eventType = getArgument("--type");
const eventStatus = getArgument("--status");
const sequence = Number(getArgument("--sequence"));
const payloadPath = getArgument("--payload");
const txHash = getArgument("--tx-hash");

if (!eventType || !eventStatus || !Number.isSafeInteger(sequence) || !payloadPath) {
  throw new Error("Usage: npm run emit -- --type <type> --status <status> --sequence <n> --payload <json-file> [--tx-hash <hash>]");
}

const environment = environmentSchema.parse(process.env);
const payload = JSON.parse(await readFile(payloadPath, "utf8")) as Record<string, unknown>;
const unsigned = unsignedAgentEventSchema.parse({
  version: 1,
  eventId: crypto.randomUUID(),
  agentId: environment.AGENT_ID,
  sequence,
  type: eventType,
  status: eventStatus,
  occurredAt: new Date().toISOString(),
  chainId: 4663,
  ...(txHash ? { txHash } : {}),
  payload,
});

const account = privateKeyToAccount(environment.EVM_PRIVATE_KEY as `0x${string}`);
const signature = await account.signMessage({ message: eventSigningMessage(unsigned) });
const event: SignedAgentEvent = { ...unsigned, signer: account.address, signature };

const response = await fetch(environment.AGENT_EVENT_ENDPOINT, {
  method: "POST",
  headers: { "content-type": "application/json" },
  body: JSON.stringify(event),
});

if (!response.ok) {
  throw new Error(`Event endpoint rejected the event (${response.status}): ${await response.text()}`);
}

process.stdout.write(`${JSON.stringify(await response.json(), null, 2)}\n`);
