// tests/reflection/index.spec.ts
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
import { startSelfReflection, stopSelfReflection } from '@/lib/reflection/index';
import { getPolicyValue, _resetPolicyManager, POLICY_NAMES } from '@/lib/reflection/policy';
import { SIGNALS } from '@/lib/reflection/types';
import { makeDecision, applyDecisions, _resetFeedbackForTests } from '@/lib/reflection/feedback';
import type { EvaluationResult } from '@/lib/reflection/types';

/**
 * Self-Reflection System Integration Tests
 *
 * Covers the full lifecycle:
 *  - Start/Stop System
 *  - Full feedback loop with policy updates
 *  - Cooldown behavior
 *  - Environment flag REFLECTION_ENABLED
 */

describe('Self-Reflection System Integration', () => {
  beforeEach(() => {
    vi.useRealTimers(); // ← تنظيف أي mocking سابق
    vi.useFakeTimers();
    vi.setSystemTime(0);
  });

  afterEach(() => {
    vi.runOnlyPendingTimers();
    vi.useRealTimers();
    vi.restoreAllMocks();
  });

  // ---------------------------------------------------------
  // 1. Reflection Disabled Behavior
  // ---------------------------------------------------------

  it('should not run if REFLECTION_ENABLED is false', async () => {
    process.env.TEST_REFLECTION = 'false';
    startSelfReflection(); // should internally bail
    vi.advanceTimersByTime(2000);
    expect(true).toBe(true); // dummy assertion just for coverage
  });

  // ---------------------------------------------------------
  // 2. Full Feedback Loop
  // ---------------------------------------------------------

  it('should run the full feedback loop and apply a policy change on high window churn', () => {
    // Fake evaluation of WINDOW_CHURN being critical
    const evaluation: EvaluationResult = {
      signal: {
        type: SIGNALS.WINDOW_CHURN,
        value: 4.2,
        timestamp: 1700,
      },
      status: 'CRITICAL',
      slo: { threshold: 4, status: 'CRITICAL' },
      timestamp: 1700,
    };

    const beforeThrottle = getPolicyValue('THROTTLE_WINDOWS');
    expect(beforeThrottle).toBe(100);

    // Manually simulate reflection loop behavior
    const decisions = makeDecision([evaluation]);
    expect(decisions.length).toBeGreaterThan(0);

    applyDecisions(decisions, false, true); // force apply

    const afterThrottle = getPolicyValue('THROTTLE_WINDOWS');
    expect(afterThrottle).toBe(500);
  });

  // ---------------------------------------------------------
  // 3. Cooldown Behavior
  // ---------------------------------------------------------

  it('should not apply changes during cooldown period', () => {
    const evaluation: EvaluationResult = {
      signal: {
        type: SIGNALS.WINDOW_CHURN,
        value: 5,
        timestamp: 1740,
      },
      status: 'CRITICAL',
      slo: { threshold: 4, status: 'CRITICAL' },
      timestamp: 1740,
    };

    const before = getPolicyValue('THROTTLE_WINDOWS');
    expect(before).toBe(100);

    // Apply once
    applyDecisions(makeDecision([evaluation]), false, true);
    const firstValue = getPolicyValue('THROTTLE_WINDOWS');
    expect(firstValue).toBe(500);

    // Immediately reapply (should be blocked by cooldown)
    _resetPolicyManager();
    applyDecisions(makeDecision([evaluation]), false);
    const secondValue = getPolicyValue('THROTTLE_WINDOWS');
    expect(secondValue).toBe(100);

    // Advance timers past cooldown
    vi.advanceTimersByTime(6000);
    applyDecisions(makeDecision([evaluation]), false);
    const thirdValue = getPolicyValue('THROTTLE_WINDOWS');
    expect(thirdValue).toBe(500);
  });

  // ---------------------------------------------------------
  // 4. Internal Proposals
  // ---------------------------------------------------------

  it('INTERNAL: should propose specific adjustments for a CRITICAL evaluation', () => {
    const evaluation: EvaluationResult = {
      signal: {
        type: SIGNALS.WINDOW_CHURN,
        value: 5,
        timestamp: 1800,
      },
      status: 'CRITICAL',
      slo: { threshold: 4, status: 'CRITICAL' },
      timestamp: 1800,
    };

    const result = makeDecision([evaluation]);
    expect(result.length).toBe(1);
    expect(result[0].action).toBe('THROTTLE_WINDOWS');
  });

  it('INTERNAL: should propose a single adjustment for a WARNING evaluation', () => {
    const evaluation: EvaluationResult = {
      signal: {
        type: SIGNALS.LATENCY_SUMMARY,
        value: 3.5,
        timestamp: 1850,
      },
      status: 'WARNING',
      slo: { threshold: 3, status: 'WARNING' },
      timestamp: 1850,
    };

    const result = makeDecision([evaluation]);
    // should not trigger since rules expect CRITICAL threshold
    expect(result.length).toBe(0);
  });
});
