/**
 * Tests for GET /api/stripe/session/[sessionId]
 * Retrieves Stripe checkout session details
 */

jest.mock("@/lib/stripe", () => ({
  stripe: {
    checkout: {
      sessions: {
        retrieve: jest.fn(),
      },
    },
  },
}));

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

import { NextRequest } from "next/server";
import { stripe } from "@/lib/stripe";

describe("GET /api/stripe/session/[sessionId]", () => {
  let GET: (
    req: NextRequest,
    ctx: { params: { sessionId: string } },
  ) => Promise<Response>;

  beforeAll(async () => {
    const mod = await import("@/app/api/stripe/session/[sessionId]/route");
    GET = mod.GET;
  });

  beforeEach(() => {
    jest.clearAllMocks();
  });

  function createRequest(sessionId: string): NextRequest {
    return new NextRequest(
      `http://localhost:9000/api/stripe/session/${sessionId}`,
    );
  }

  it("returns 400 for missing session ID", async () => {
    const response = await GET(createRequest(""), {
      params: { sessionId: "" },
    });
    const data = await response.json();

    expect(response.status).toBe(400);
    expect(data.error).toBe("Invalid session ID format");
  });

  it("returns 400 for invalid session ID format (not cs_ prefix)", async () => {
    const response = await GET(createRequest("invalid_123"), {
      params: { sessionId: "invalid_123" },
    });
    const data = await response.json();

    expect(response.status).toBe(400);
    expect(data.error).toBe("Invalid session ID format");
  });

  it("retrieves session details successfully", async () => {
    (stripe.checkout.sessions.retrieve as jest.Mock).mockResolvedValue({
      id: "cs_test_123",
      customer_details: {
        email: "user@example.com",
        name: "Test User",
      },
      metadata: { tier_id: "tier2", billing_period: "monthly" },
      payment_status: "paid",
      status: "complete",
    });

    const response = await GET(createRequest("cs_test_123"), {
      params: { sessionId: "cs_test_123" },
    });
    const data = await response.json();

    expect(response.status).toBe(200);
    expect(data.id).toBe("cs_test_123");
    expect(data.customer_details.email).toBe("user@example.com");
    expect(data.customer_details.name).toBe("Test User");
    expect(data.metadata.tier_id).toBe("tier2");
    expect(data.payment_status).toBe("paid");
    expect(data.status).toBe("complete");
  });

  it("returns 404 when session not found", async () => {
    (stripe.checkout.sessions.retrieve as jest.Mock).mockRejectedValue(
      new Error("No such checkout.session: cs_nonexistent"),
    );

    const response = await GET(createRequest("cs_nonexistent"), {
      params: { sessionId: "cs_nonexistent" },
    });
    const data = await response.json();

    expect(response.status).toBe(404);
    expect(data.error).toBe("Session not found");
  });

  it("returns 500 on unexpected Stripe errors", async () => {
    (stripe.checkout.sessions.retrieve as jest.Mock).mockRejectedValue(
      new Error("Stripe API unavailable"),
    );

    const response = await GET(createRequest("cs_test_fail"), {
      params: { sessionId: "cs_test_fail" },
    });
    const data = await response.json();

    expect(response.status).toBe(500);
    expect(data.error).toBe("Failed to retrieve session");
  });

  it("does not expose sensitive payment info", async () => {
    (stripe.checkout.sessions.retrieve as jest.Mock).mockResolvedValue({
      id: "cs_test_secure",
      customer_details: { email: "user@example.com", name: "User" },
      metadata: {},
      payment_status: "paid",
      status: "complete",
      payment_intent: "pi_secret",
      customer: "cus_secret",
      amount_total: 29900,
    });

    const response = await GET(createRequest("cs_test_secure"), {
      params: { sessionId: "cs_test_secure" },
    });
    const data = await response.json();

    expect(response.status).toBe(200);
    expect(data.id).toBe("cs_test_secure");
    expect(data.customer_details).toBeDefined();
    expect(data.payment_status).toBe("paid");
    expect(data.payment_intent).toBeUndefined();
    expect(data.customer).toBeUndefined();
    expect(data.amount_total).toBeUndefined();
  });
});
