import { describe, expect, test } from "bun:test";
import { VoicePolicyProxy, type SchedulingToolPort } from "./policy-proxy.ts";

describe("VoicePolicyProxy", () => {
  test("blocks reschedule tool when write approval is absent", async () => {
    const proxy = new VoicePolicyProxy(fakeScheduling());
    const result = await proxy.handleToolCall({
      id: "tc1",
      name: "request_reschedule",
      arguments: { appointment_id: "a1", slot_id: "s1" },
    });
    expect(result.action).toBe("approval_required");
  });

  test("routes escalation language to staff", async () => {
    const proxy = new VoicePolicyProxy(fakeScheduling());
    const result = await proxy.handleToolCall({
      id: "tc1",
      name: "assess_escalation",
      arguments: { text: "I have shortness of breath" },
    });
    expect(result.action).toBe("transfer_to_staff");
  });

  test("lets scheduling port enforce patient verification before approval gating", async () => {
    const proxy = new VoicePolicyProxy({
      ...fakeScheduling(),
      async requestReschedule() {
        return {
          ok: false,
          action: "transfer_to_staff",
          message: "patient not verified",
          data: { reason: "patient_not_verified" },
        };
      },
    });
    const result = await proxy.handleToolCall({
      id: "tc1",
      name: "request_reschedule",
      arguments: { patient_id: "p1", appointment_id: "a1" },
    });
    expect(result.action).toBe("transfer_to_staff");
    expect(result.data?.reason).toBe("patient_not_verified");
  });
});

function fakeScheduling(): SchedulingToolPort {
  return {
    async verifyPatientIdentity() {
      return { ok: true, action: "continue", message: "verified" };
    },
    async findRescheduleOptions() {
      return { ok: true, action: "offer_slots", message: "slots", data: {} };
    },
    async requestReschedule() {
      return { ok: true, action: "continue", message: "rescheduled" };
    },
    async createCallback() {
      return { ok: true, action: "callback_required", message: "callback" };
    },
    async transferToStaff() {
      return { ok: true, action: "transfer_to_staff", message: "transfer" };
    },
  };
}
