/**
 * Tests for Voice Booking Cancellation API
 *
 * Tests the /api/bookings/voice/cancel endpoint
 */

import { NextRequest } from "next/server";

// Mock dependencies
jest.mock("@/lib/db");

jest.mock("@/lib/logger", () => ({
  logger: {
    info: jest.fn(),
    warn: jest.fn(),
    error: jest.fn(),
  },
}));

// Route not yet implemented - imports skipped
let POST: any;
import { prisma } from "@/lib/db";

// Voice agent routes not yet implemented
describe.skip("POST /api/bookings/voice/cancel", () => {
  beforeEach(() => {
    jest.clearAllMocks();
  });

  const createRequest = (body: Record<string, unknown>) => {
    return new NextRequest("http://localhost/api/bookings/voice/cancel", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify(body),
    });
  };

  it("should return 400 if booking_id is missing", async () => {
    const request = createRequest({
      phone_number: "+1234567890",
    });

    const response = await POST(request);

    expect(response.status).toBe(400);
    const data = await response.json();
    expect(data.error).toBe("Invalid cancellation data");
  });

  it("should return 404 if booking is not found", async () => {
    (prisma.bookings.findUnique as jest.Mock).mockResolvedValue(null);

    const request = createRequest({
      booking_id: "booking-123",
      phone_number: "+1234567890",
    });

    const response = await POST(request);

    expect(response.status).toBe(404);
    const data = await response.json();
    expect(data.error).toBe("Booking not found");
  });

  it("should return 403 if phone number does not match", async () => {
    (prisma.bookings.findUnique as jest.Mock).mockResolvedValue({
      id: "booking-123",
      customerPhone: "+9999999999",
      customerName: "John Doe",
      service: "Checkup",
      status: "pending",
    });

    const request = createRequest({
      booking_id: "booking-123",
      phone_number: "+1234567890",
    });

    const response = await POST(request);

    expect(response.status).toBe(403);
    const data = await response.json();
    expect(data.error).toBe("Phone number does not match booking");
  });

  it("should return 400 if booking is already cancelled", async () => {
    (prisma.bookings.findUnique as jest.Mock).mockResolvedValue({
      id: "booking-123",
      customerPhone: "+1234567890",
      customerName: "John Doe",
      service: "Checkup",
      status: "cancelled",
    });

    const request = createRequest({
      booking_id: "booking-123",
      phone_number: "+1234567890",
    });

    const response = await POST(request);

    expect(response.status).toBe(400);
    const data = await response.json();
    expect(data.error).toBe("Booking is already cancelled");
  });

  it("should return 400 if booking is completed", async () => {
    (prisma.bookings.findUnique as jest.Mock).mockResolvedValue({
      id: "booking-123",
      customerPhone: "+1234567890",
      customerName: "John Doe",
      service: "Checkup",
      status: "completed",
    });

    const request = createRequest({
      booking_id: "booking-123",
      phone_number: "+1234567890",
    });

    const response = await POST(request);

    expect(response.status).toBe(400);
    const data = await response.json();
    expect(data.error).toBe("Cannot cancel a completed appointment");
  });

  it("should cancel booking successfully", async () => {
    (prisma.bookings.findUnique as jest.Mock).mockResolvedValue({
      id: "booking-123",
      customerPhone: "+1234567890",
      customerName: "John Doe",
      service: "Dental Checkup",
      appointmentDate: new Date("2024-01-20"),
      appointmentTime: "10:00",
      status: "pending",
      userId: "user-1",
    });

    (prisma.bookings.update as jest.Mock).mockResolvedValue({});

    const request = createRequest({
      booking_id: "booking-123",
      phone_number: "+1234567890",
      reason: "Schedule conflict",
    });

    const response = await POST(request);

    expect(response.status).toBe(200);
    const data = await response.json();

    expect(data.success).toBe(true);
    expect(data.message).toContain("cancelled");
    expect(data.cancelled_booking.id).toBe("booking-123");

    // Verify booking was updated
    expect(prisma.bookings.update).toHaveBeenCalledWith({
      where: { id: "booking-123" },
      data: expect.objectContaining({
        status: "cancelled",
        notes: expect.stringContaining("Schedule conflict"),
      }),
    });
  });

  it("should allow partial phone number match (last 10 digits)", async () => {
    (prisma.bookings.findUnique as jest.Mock).mockResolvedValue({
      id: "booking-123",
      customerPhone: "+11234567890", // US format with country code
      customerName: "John Doe",
      service: "Checkup",
      appointmentDate: new Date("2024-01-20"),
      appointmentTime: "10:00",
      status: "pending",
      userId: "user-1",
    });

    (prisma.bookings.update as jest.Mock).mockResolvedValue({});

    const request = createRequest({
      booking_id: "booking-123",
      phone_number: "1234567890", // Without country code
    });

    const response = await POST(request);

    expect(response.status).toBe(200);
    const data = await response.json();
    expect(data.success).toBe(true);
  });
});
