import { describe, expect, it } from "vitest";
import { appRouter } from "./routers";
import { canCheckInTicket, canManageEvent, canReviewPayment, shouldRevealPaidTickets } from "./db";
import type { TrpcContext } from "./_core/context";

const caller = () => appRouter.createCaller({ user: null, req: {} as TrpcContext["req"], res: {} as TrpcContext["res"] });

describe("gngtickets MTN Mobile Money flow", () => {
  it("rejects an empty transaction ID before any payment record is created", async () => {
    await expect(caller().checkout.submitMtnPayment({ orderId: 1, payerName: "Guest", payerPhone: "0550000000", transactionId: "", amountMinor: 1000 })).rejects.toMatchObject({ code: "BAD_REQUEST" });
  });

  it("keeps paid tickets hidden until both order and payment are approved", () => {
    expect(shouldRevealPaidTickets("pending", "pending")).toBe(false);
    expect(shouldRevealPaidTickets("paid", "pending")).toBe(false);
    expect(shouldRevealPaidTickets("paid", "approved")).toBe(true);
  });

  it("allows only the event owner or an admin to review a payment", () => {
    expect(canReviewPayment(7, 8, "user")).toBe(false);
    expect(canReviewPayment(7, 7, "user")).toBe(true);
    expect(canReviewPayment(7, 8, "admin")).toBe(true);
  });

  it("allows only the event owner or an admin to edit or cancel an event", () => {
    expect(canManageEvent(42, 42, "user")).toBe(true);
    expect(canManageEvent(42, 99, "user")).toBe(false);
    expect(canManageEvent(42, 99, "admin")).toBe(true);
  });

  it("allows only the event owner or an admin to check in a ticket", () => {
    expect(canCheckInTicket(42, 42, "user")).toBe(true);
    expect(canCheckInTicket(42, 99, "user")).toBe(false);
    expect(canCheckInTicket(42, 99, "admin")).toBe(true);
  });

  it("does not allow unauthenticated users to approve a payment or reveal tickets", async () => {
    await expect(caller().events.reviewPayment({ paymentId: 1, decision: "approved" })).rejects.toMatchObject({ code: "UNAUTHORIZED" });
  });
});
