import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import {
  clearEvolutionLogs,
  getEvolutionLogs,
  logSnapshot,
  startAutoSnapshot,
  stopAutoSnapshot,
} from '@/lib/evolution/history.collector';
import * as meta from '@/lib/evolution/meta-forecast';

describe('Evolution Logs Collector', () => {
  beforeEach(() => {
    clearEvolutionLogs();
    vi.restoreAllMocks();
    vi.spyOn(meta, 'generateMetaForecast').mockReturnValue({
      trend: 'Reform',
      confidence: 0.84,
      changeRate: 0,
      recommendation: 'ok',
      timestamp: new Date().toISOString(),
    });
  });

  afterEach(() => {
    stopAutoSnapshot();
    vi.restoreAllMocks();
  });

  it('logs manual snapshot', () => {
    const row = logSnapshot({ notes: 'manual' });
    expect(row.trend).toBe('Reform');
    const rows = getEvolutionLogs();
    expect(rows.length).toBe(1);
    expect(rows[0].notes).toBe('manual');
  });

  it('auto-snapshot records delta change properly', async () => {
    let callCount = 0;

    // نخليها ترجع "Reform" أول مرة و"Integrate" بعد كده
    vi.spyOn(meta, 'generateMetaForecast').mockImplementation(() => {
      callCount++;
      if (callCount < 2) {
        return {
          trend: 'Reform',
          confidence: 0.84,
          changeRate: 0,
          recommendation: 'ok',
          timestamp: new Date().toISOString(),
        };
      }
      return {
        trend: 'Integrate',
        confidence: 0.95,
        changeRate: 0.2,
        recommendation: 'rise',
        timestamp: new Date().toISOString(),
      };
    });

    // start auto snapshot بسرعة
    startAutoSnapshot({ intervalSec: 0.05, confidenceDelta: 0.05 });

    // نستنى وقت كفاية للـ interval يسجّل 2 snapshots
    await new Promise((r) => setTimeout(r, 800));

    const rows = getEvolutionLogs();

    // تأكيد إن على الأقل اتسجل اتنين
    expect(rows.length).toBeGreaterThanOrEqual(2);

    // تأكيد إن في واحد منهم trend = Integrate
    const hasIntegrate = rows.some((l) => l.trend === 'Integrate');
    expect(hasIntegrate).toBe(true);
  });
});
