/**
 * P1-3 fix — analytics time-range filter must respect the requested range.
 *
 * Bug from the SRS audit: dashboard sets `range: '7d'` (user picked "Last
 * 7 days"), but the response comes back with `range: '6m'`. Root cause:
 * the timeseries endpoint only understood month-granularity ranges and
 * silently coerced anything else to 6m.
 *
 * The fix: the endpoint now honours 7d/30d/90d with daily granularity
 * and echoes the requested `range` back in the response. This test
 * pins that contract.
 */

const request = require('supertest');
const { pointAtDevDb } = require('./setup');

pointAtDevDb();

const app = require('../src/index');

describe('Reports — time-series range filter (P1-3)', () => {
  let adminToken;

  beforeAll(async () => {
    const res = await request(app)
      .post('/api/auth/login')
      .send({ email: 'admin@school.com', password: 'admin123' });
    adminToken = res.body?.token;
  });

  it('honours range=7d and returns 7 daily points', async () => {
    const res = await request(app)
      .get('/api/reports/timeseries?range=7d')
      .set('Authorization', `Bearer ${adminToken}`);
    expect(res.status).toBe(200);
    expect(res.body.range).toBe('7d');
    expect(Array.isArray(res.body.series)).toBe(true);
    expect(res.body.series).toHaveLength(7);
    // Daily points carry a YYYY-MM-DD `date` key
    for (const p of res.body.series) {
      expect(p.date).toMatch(/^\d{4}-\d{2}-\d{2}$/);
    }
  });

  it('honours range=30d and returns 30 daily points', async () => {
    const res = await request(app)
      .get('/api/reports/timeseries?range=30d')
      .set('Authorization', `Bearer ${adminToken}`);
    expect(res.status).toBe(200);
    expect(res.body.range).toBe('30d');
    expect(res.body.series).toHaveLength(30);
  });

  it('honours range=90d and returns 90 daily points', async () => {
    const res = await request(app)
      .get('/api/reports/timeseries?range=90d')
      .set('Authorization', `Bearer ${adminToken}`);
    expect(res.status).toBe(200);
    expect(res.body.range).toBe('90d');
    expect(res.body.series).toHaveLength(90);
  });

  it('still honours range=6m (12 buckets back) for backward compat', async () => {
    const res = await request(app)
      .get('/api/reports/timeseries?range=6m')
      .set('Authorization', `Bearer ${adminToken}`);
    expect(res.status).toBe(200);
    expect(res.body.range).toBe('6m');
    expect(res.body.series).toHaveLength(6);
    // Monthly points carry a yearMonth key
    for (const p of res.body.series) {
      expect(p.yearMonth).toMatch(/^\d{4}-\d{2}$/);
    }
  });

  it('defaults to 6 months when no range is given', async () => {
    const res = await request(app)
      .get('/api/reports/timeseries')
      .set('Authorization', `Bearer ${adminToken}`);
    expect(res.status).toBe(200);
    expect(res.body.range).toBe('6m');
    expect(res.body.series).toHaveLength(6);
  });

  it('rejects a teacher token without a student data leak (RBAC unchanged)', async () => {
    const login = await request(app)
      .post('/api/auth/login')
      .send({ email: 'teacher@school.com', password: 'teacher123' });
    const teacherToken = login.body?.token;
    const res = await request(app)
      .get('/api/reports/timeseries?range=7d')
      .set('Authorization', `Bearer ${teacherToken}`);
    // reports.controller.js uses adminOrTeacher on /timeseries.
    expect(res.status).toBe(200);
    expect(res.body.range).toBe('7d');
    expect(res.body.series).toHaveLength(7);
  });
});
