import { describe, it, expect, vi } from "vitest";

import {
  GlobalOrderCoordinator,
  type GlobalOrderSnapshot,
  type ValidationIntent
} from "../packages/execution/src/globalOrderCoordinator";

function makeSnapshot(partial: Partial<GlobalOrderSnapshot>): GlobalOrderSnapshot {
  return {
    orderId: partial.orderId ?? "order-1",
    clientOrderId: partial.clientOrderId,
    accountId: partial.accountId ?? "maker",
    symbol: partial.symbol ?? "BTC",
    side: partial.side ?? "buy",
    price: partial.price ?? 50_000,
    timestamp: partial.timestamp ?? Date.now()
  };
}

describe("GlobalOrderCoordinator", () => {
  it("registers and releases orders", () => {
    const coordinator = new GlobalOrderCoordinator();
    const snapshot = makeSnapshot({ clientOrderId: "client-1" });

    coordinator.register(snapshot);
    expect(coordinator.list()).toHaveLength(1);
    expect(coordinator.peek(snapshot.orderId)).toEqual(snapshot);
    expect(coordinator.peekByClientId("client-1")).toEqual(snapshot);

    coordinator.release(snapshot.orderId);
    expect(coordinator.list()).toHaveLength(0);
    expect(coordinator.peek(snapshot.orderId)).toBeUndefined();
    expect(coordinator.peekByClientId("client-1")).toBeUndefined();
  });

  it("detects cross-account conflicts", () => {
    const coordinator = new GlobalOrderCoordinator();
    coordinator.register(makeSnapshot({ orderId: "sell-1", side: "sell", price: 50_100 }));

    const onConflict = vi.fn();
    coordinator.on("conflict", onConflict);

    const intent: ValidationIntent = {
      accountId: "hedger",
      symbol: "BTC",
      side: "buy",
      price: 50_200
    };

    expect(() => coordinator.validate(intent)).toThrow(/STP violation/);
    expect(onConflict).toHaveBeenCalledTimes(1);
    const payload = onConflict.mock.calls[0][0];
    expect(payload.intent).toEqual(intent);
    expect(payload.conflicts).toHaveLength(1);
    expect(payload.conflicts[0].orderId).toBe("sell-1");
  });

  it("ignores orders from the same account", () => {
    const coordinator = new GlobalOrderCoordinator();
    coordinator.register(makeSnapshot({ orderId: "sell-1", accountId: "maker", side: "sell" }));

    expect(() =>
      coordinator.validate({
        accountId: "maker",
        symbol: "BTC",
        side: "buy",
        price: 49_900
      })
    ).not.toThrow();
  });

  it("respects tolerance when evaluating potential crosses", () => {
    const coordinator = new GlobalOrderCoordinator({ stpToleranceBps: 5 });
    coordinator.register(makeSnapshot({ orderId: "ask-1", side: "sell", price: 50_000 }));

    // Within tolerance -> treated as conflict.
    expect(() =>
      coordinator.validate({
        accountId: "hedger",
        symbol: "BTC",
        side: "buy",
        price: 50_020
      })
    ).toThrow();

    // Far away (non-cross) -> no conflict.
    expect(() =>
      coordinator.validate({
        accountId: "hedger",
        symbol: "BTC",
        side: "buy",
        price: 49_000
      })
    ).not.toThrow();
  });
});
