/**
 * Tests for GET /api/dashboard/stats
 *
 * Covers:
 * - 401 when unauthenticated
 * - 200 returns aggregated stats from all repositories
 * - Response shape includes users, tokens, usage, audit sections
 */

import { describe, it, expect, vi, beforeEach } from 'vitest';

const mockRequireAdmin = vi.fn();
vi.mock('@/lib/auth-server', () => ({
  requireAdmin: (...args: unknown[]) => mockRequireAdmin(...args),
  getCurrentUser: (...args: unknown[]) => mockRequireAdmin(...args),
  getCurrentUserFromRequest: (...args: unknown[]) => mockRequireAdmin(...args),
}));

const mockCountActiveTokens = vi.fn();
vi.mock('@/lib/repositories/tokens', () => ({
  countActiveTokens: (...args: unknown[]) => mockCountActiveTokens(...args),
}));

const mockGetUsageSummary = vi.fn();
vi.mock('@/lib/billing-client', () => ({
  getUsageSummary: (...args: unknown[]) => mockGetUsageSummary(...args),
}));

const mockGetUserCounts = vi.fn();
const mockGetAuditStats = vi.fn();
vi.mock('@/lib/platform-client', () => ({
  getUserCounts: (...args: unknown[]) => mockGetUserCounts(...args),
  getAuditStats: (...args: unknown[]) => mockGetAuditStats(...args),
}));

import { GET } from '@/app/api/dashboard/stats/route';

async function callStats(token?: string) {
  const { NextRequest } = await import('next/server');
  const headers: Record<string, string> = {};
  if (token) headers['Authorization'] = token;
  return GET(
    new NextRequest(new Request('http://localhost:3001/api/dashboard/stats', { headers }))
  );
}

const admin = { id: 'usr_a', email: 'a@example.com', name: 'Admin', role: 'admin' };

describe('GET /api/dashboard/stats', () => {
  beforeEach(() => vi.clearAllMocks());

  it('returns 401 when unauthenticated', async () => {
    mockRequireAdmin.mockResolvedValue(null);
    const res = await callStats();
    expect(res.status).toBe(401);
  });

  it('returns aggregated stats on success', async () => {
    mockRequireAdmin.mockResolvedValue(admin);
    mockGetUserCounts.mockResolvedValue({
      total: 150,
      byPlan: { free: 100, pro: 40, enterprise: 10 },
    });
    mockCountActiveTokens.mockResolvedValue(25);
    mockGetUsageSummary.mockResolvedValue({
      totalWords: 500000,
      totalDictations: 12000,
      totalCost: 245.5,
    });
    mockGetAuditStats.mockResolvedValue({
      stats: { login_success: 8868, login_failed: 32 },
      days: 90,
    });

    const res = await callStats('Bearer valid_token');
    expect(res.status).toBe(200);
    const data = await res.json();

    // Users section
    expect(data.users.total).toBe(150);
    expect(data.users.byPlan.free).toBe(100);
    expect(data.users.byPlan.pro).toBe(40);
    expect(data.users.byPlan.enterprise).toBe(10);

    // Tokens section
    expect(data.tokens.active).toBe(25);

    // Usage section
    expect(data.usage.totalWords).toBe(500000);
    expect(data.usage.totalDictations).toBe(12000);
    expect(data.usage.totalCost).toBe(245.5);

    // Audit section
    expect(data.audit.total).toBe(8900);
    expect(data.audit.failedLogins).toBe(32);
  });

  it('passes 30 days to getUsageSummary', async () => {
    mockRequireAdmin.mockResolvedValue(admin);
    mockGetUserCounts.mockResolvedValue({ total: 0, byPlan: {} });
    mockCountActiveTokens.mockResolvedValue(0);
    mockGetUsageSummary.mockResolvedValue({
      totalWords: 0,
      totalDictations: 0,
      totalCost: 0,
    });
    mockGetAuditStats.mockResolvedValue({ stats: {}, days: 90 });

    await callStats('Bearer valid_token');
    expect(mockGetUsageSummary).toHaveBeenCalledWith(30);
  });
});
