import { describe, it, expect, vi, beforeEach } from "vitest";
import fastify, { type FastifyReply, type FastifyRequest } from "fastify";
import type { Pool } from "mysql2/promise";
import type { AppConfig } from "../../config.js";
import { registerPaymentsRoutes } from "../payments-routes.js";
import type { RouteContext } from "../types.js";

const makeConfig = (): AppConfig => ({
  appEnv: "test",
  host: "127.0.0.1",
  port: 0,
  ads: { enabled: false },
  auth: { jwtSecret: "test" },
  cookies: { sameSite: "lax", secure: false },
  smtp: { secure: false },
  db: {
    host: "localhost",
    port: 3306,
    name: "test",
    user: "test",
    password: "test",
    poolSize: 1,
    ssl: false,
    sslRejectUnauthorized: true,
  },
});

const makeDb = () =>
  ({
    execute: vi.fn(async () => {
      throw new Error("DB non attendu");
    }),
  }) as unknown as Pool;

const makeCtx = (): RouteContext => ({
  db: makeDb(),
  config: makeConfig(),
  mailer: null,
  signAccessToken: () => "access",
  signRefreshToken: () => "refresh",
  setRefreshCookie: () => undefined,
  getRefreshCookie: () => undefined,
  clearRefreshCookie: () => undefined,
  requireAuth: async (request: FastifyRequest, _reply: FastifyReply) => {
    (
      request as FastifyRequest & { user?: { sub: number; email: string } }
    ).user = {
      sub: 1,
      email: "test@example.com",
    };
  },
  requireAdmin: async () => undefined,
  packageVersion: "test",
  appEnv: "test",
});

describe("payments-routes", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("retourne 503 si Stripe non configuré (checkout-session)", async () => {
    const app = fastify();
    await registerPaymentsRoutes(app, makeCtx());

    const response = await app.inject({
      method: "POST",
      url: "/payments/stripe/checkout-session",
      payload: { packId: "starter" },
    });

    expect(response.statusCode).toBe(503);
  });

  it("retourne 503 si Stripe non configuré (checkout-cash)", async () => {
    const app = fastify();
    await registerPaymentsRoutes(app, makeCtx());

    const response = await app.inject({
      method: "POST",
      url: "/payments/stripe/checkout-cash",
      payload: { packId: "silver" },
    });

    expect(response.statusCode).toBe(503);
  });
});
