import { describe, expect, it, jest } from '@jest/globals';

const getRateLimit = jest.fn<() => Promise<number>>();
let mockRateLimitOptions: any;
jest.mock('../../../services/tierService', () => ({ tierService: { getRateLimit } }));
jest.mock('ioredis', () => jest.fn().mockImplementation(() => ({
  on: jest.fn(),
  call: jest.fn(),
})));
jest.mock('express-rate-limit', () => jest.fn((options) => {
  mockRateLimitOptions ??= options;
  return jest.fn();
}));
jest.mock('rate-limit-redis', () => jest.fn());

import { apiRateLimiter, resolveRequestRateLimit } from '../../../middleware/rateLimiter';

describe('tier rate limiting', () => {
  it('resolves the authoritative tier limit within the authenticated plugin', async () => {
    getRateLimit.mockResolvedValueOnce(0);

    await expect(resolveRequestRateLimit({
      user: { plan: 'enterprise', plugin: 'international' },
    } as any)).resolves.toBe(0);

    expect(getRateLimit).toHaveBeenCalledWith('enterprise', 'international');
  });

  it('shares one plugin-scoped lookup between unlimited bypass and rate enforcement', async () => {
    const request = {
      user: { plan: 'professional', plugin: 'international' },
    } as any;

    getRateLimit.mockResolvedValueOnce(100);

    await apiRateLimiter(request, {} as any, jest.fn());
    await expect(mockRateLimitOptions.max(request)).resolves.toBe(100);
    expect(getRateLimit).toHaveBeenCalledTimes(1);
  });

  it('bypasses an enterprise tier only when its resolved limit is exactly zero', async () => {
    const next = jest.fn();

    getRateLimit.mockResolvedValueOnce(100);
    await apiRateLimiter({
      user: { plan: 'enterprise', plugin: 'international' },
    } as any, {} as any, next);
    expect(next).not.toHaveBeenCalled();

    getRateLimit.mockResolvedValueOnce(0);
    await apiRateLimiter({
      user: { plan: 'enterprise', plugin: 'international' },
    } as any, {} as any, next);
    expect(next).toHaveBeenCalledTimes(1);
  });
});
