import { describe, expect, it, vi, beforeAll, afterAll, beforeEach } from 'vitest';
import { createServiceApp, type FastifyApp } from '@bytelyst/fastify-core';

vi.mock('../../lib/config.js', () => ({
  config: {
    SERVICE_NAME: 'cowork-service',
    PLATFORM_SERVICE_URL: 'http://mock-platform:4003',
  },
}));
vi.mock('../../lib/product-config.js', () => ({
  PRODUCT_ID: 'clawcowork',
}));

import { auditRoutes } from './routes.js';

let app: FastifyApp;

const mockFetch = vi.fn();
vi.stubGlobal('fetch', mockFetch);

beforeAll(async () => {
  app = await createServiceApp({
    name: 'audit-routes-test',
    version: '0.0.1',
    logger: false,
  });
  await app.register(auditRoutes);
});

afterAll(async () => {
  await app.close();
});

beforeEach(() => {
  mockFetch.mockReset();
});

describe('audit proxy routes', () => {
  describe('GET /api/audit', () => {
    it('proxies to platform-service and returns records', async () => {
      mockFetch.mockResolvedValue({
        ok: true,
        json: async () => ({ records: [{ id: 'aud_1', action: 'tool_call' }], count: 1 }),
      });

      const res = await app.inject({ method: 'GET', url: '/api/audit?limit=50&days=7' });

      expect(res.statusCode).toBe(200);
      const body = JSON.parse(res.payload);
      expect(body.records).toHaveLength(1);
      expect(mockFetch).toHaveBeenCalledOnce();
      const fetchUrl = mockFetch.mock.calls[0][0] as string;
      expect(fetchUrl).toContain('mock-platform:4003/audit');
      expect(fetchUrl).toContain('limit=50');
      expect(fetchUrl).toContain('days=7');
    });

    it('returns 502 when platform-service is unreachable', async () => {
      mockFetch.mockRejectedValue(new Error('ECONNREFUSED'));

      const res = await app.inject({ method: 'GET', url: '/api/audit' });

      expect(res.statusCode).toBe(502);
      const body = JSON.parse(res.payload);
      expect(body.error).toBe('Platform-service unavailable');
    });

    it('forwards platform non-ok status', async () => {
      mockFetch.mockResolvedValue({ ok: false, status: 403 });

      const res = await app.inject({ method: 'GET', url: '/api/audit' });

      expect(res.statusCode).toBe(403);
    });
  });

  describe('GET /api/audit/stats', () => {
    it('proxies stats request to platform-service', async () => {
      mockFetch.mockResolvedValue({
        ok: true,
        json: async () => ({ stats: { total: 42 }, days: 30 }),
      });

      const res = await app.inject({ method: 'GET', url: '/api/audit/stats?days=14' });

      expect(res.statusCode).toBe(200);
      const body = JSON.parse(res.payload);
      expect(body.stats.total).toBe(42);
      const fetchUrl = mockFetch.mock.calls[0][0] as string;
      expect(fetchUrl).toContain('days=14');
    });

    it('returns 502 when platform-service is unreachable', async () => {
      mockFetch.mockRejectedValue(new Error('ECONNREFUSED'));

      const res = await app.inject({ method: 'GET', url: '/api/audit/stats' });

      expect(res.statusCode).toBe(502);
    });
  });
});
