/**
 * Phase 7 — Societal Integration Test
 * -----------------------------------
 * يختبر التواصل بين عقدتين عبر CFP + IntegrationBus + SocialAdaptationEngine
 * ويتأكد من توليد Integration_Report.json بنجاح.
 */

import { describe, it, expect, beforeAll, afterAll } from 'vitest';
import fs from 'node:fs';
import path from 'node:path';
import { Bus } from '../../lib/integration/integration_bus';
import { buildMessage } from '../../lib/integration/cfp_protocol';
import {
  SocialAdaptationEngine,
  loadNodeReportsFromFiles,
  saveIntegrationReport,
} from '../../lib/integration/social_adaptation_engine';

// مسار التخزين المؤقت
const TMP_DIR = './storage/tests/phase7';
const REPORT_PATH = path.join(TMP_DIR, 'Integration_Report.json');
const NODE_A_PATH = path.join(TMP_DIR, 'nodeA_Evolution_Report.json');
const NODE_B_PATH = path.join(TMP_DIR, 'nodeB_Evolution_Report.json');

describe('🧩 Phase 7 — Societal Integration Flow', () => {
  beforeAll(() => {
    fs.mkdirSync(TMP_DIR, { recursive: true });

    // نولّد تقارير بسيطة للعقدتين
    const nodeA = {
      metrics: {
        adaptationRate: 0.25,
        stabilityIndex: 0.78,
        metaCognitionLevel: 0.62,
        nextRecommendedMutation: 'Expand',
      },
      registrySnapshot: [
        { policyId: 'POL-A', weight: 0.5 },
        { policyId: 'POL-B', weight: 0.9 },
      ],
    };

    const nodeB = {
      metrics: {
        adaptationRate: 0.21,
        stabilityIndex: 0.74,
        metaCognitionLevel: 0.58,
        nextRecommendedMutation: 'Expand',
      },
      registrySnapshot: [
        { policyId: 'POL-A', weight: 0.52 },
        { policyId: 'POL-C', weight: 0.44 },
      ],
    };

    fs.writeFileSync(NODE_A_PATH, JSON.stringify(nodeA, null, 2));
    fs.writeFileSync(NODE_B_PATH, JSON.stringify(nodeB, null, 2));
  });

  afterAll(() => {
    if (fs.existsSync(TMP_DIR)) fs.rmSync(TMP_DIR, { recursive: true, force: true });
  });

  it('should build Integration_Report.json after receiving 2 node reports via Bus', async () => {
    const engine = new SocialAdaptationEngine({ outPath: REPORT_PATH });
    engine.bindToBus(Bus);

    // عقدة A ترسل تقريرها
    const msgA = buildMessage(
      'BROADCAST_REPORT',
      {
        nodeId: 'node-A',
        report: JSON.parse(fs.readFileSync(NODE_A_PATH, 'utf8')),
      },
      { sourceId: 'node-A', trust: 0.8 }
    );

    // عقدة B ترسل تقريرها
    const msgB = buildMessage(
      'BROADCAST_REPORT',
      {
        nodeId: 'node-B',
        report: JSON.parse(fs.readFileSync(NODE_B_PATH, 'utf8')),
      },
      { sourceId: 'node-B', trust: 0.75 }
    );

    // بثّهم عبر الـ Bus
    await Bus.emit('cfp:BROADCAST_REPORT', msgA);
    await Bus.emit('cfp:BROADCAST_REPORT', msgB);

    // مهلة صغيرة للسماح للـ async handlers بالإنهاء
    await new Promise((r) => setTimeout(r, 50));

    // تحقق من توليد الملف
    expect(fs.existsSync(REPORT_PATH)).toBe(true);

    const json = JSON.parse(fs.readFileSync(REPORT_PATH, 'utf8'));
    expect(json.metrics).toBeDefined();
    expect(json.metrics.collectiveStability).toBeGreaterThan(0);
    expect(json.metrics.collaborationIndex).toBeGreaterThan(0);
    expect(json.metrics.metaResonance).toBeGreaterThan(0);
    expect(['Expand', 'Merge', 'Freeze', 'Contract']).toContain(
      json.metrics.nextEvolutionDirective
    );

    console.log('✅ Integration_Report:', json.metrics);
  });

  it('should also support direct file aggregation via loadNodeReportsFromFiles()', () => {
    const nodes = loadNodeReportsFromFiles([
      { nodeId: 'node-A', path: NODE_A_PATH, trust: 0.8 },
      { nodeId: 'node-B', path: NODE_B_PATH, trust: 0.75 },
    ]);

    expect(nodes.length).toBe(2);
    expect(nodes[0].metrics.stabilityIndex).toBeCloseTo(0.78, 2);

    const engine = new SocialAdaptationEngine({ outPath: REPORT_PATH });
    engine.ingestMany(nodes);
    const rep = engine.computeAndStore();

    expect(fs.existsSync(REPORT_PATH)).toBe(true);
    expect(rep.metrics.collectiveStability).toBeGreaterThan(0.7);
    expect(rep.metrics.collaborationIndex).toBeGreaterThan(0);
  });
});
