// lib/feedback/evaluator.ts
import type { Signal } from './types';

type Severity = 'NORMAL' | 'WARNING' | 'CRITICAL';

/**
 * 🧩 Feedback Evaluator
 * يحلل الإشارات (signals) ويولّد التقييم النهائي المستخدم في دورة التغذية الراجعة.
 * الناتج يحتوي على:
 *  - score → درجة الحالة الرقمية
 *  - severity → المستوى (NORMAL / WARNING / CRITICAL)
 *  - confidence → الثقة بالتقييم
 *  - reasons → أسباب التقييم
 *  - bucket → حالة النظام STABLE أو VOLATILE
 */
export function evaluate(signals: Signal[]) {
  // 🔍 اجمع أعلى قيمة لكل نوع من الإشارات
  const pickMax = (kind: Signal['kind']) =>
    Math.max(0, ...signals.filter((s) => s.kind === kind).map((s) => Number(s.value) || 0));

  const maxError = pickMax('ERROR');
  const maxLatency = pickMax('LATENCY');
  const maxLoad = pickMax('LOAD');
  const maxChurn = pickMax('CHURN');

  const reasons: string[] = [];

  // 🧠 الأسباب التحليلية — تُستخدم لاحقاً داخل الـ policy
  if (maxError >= 70) reasons.push('ERROR_SPIKE');
  if (maxLatency >= 70) reasons.push('LATENCY_SPIKE');
  if (maxLoad >= 60) reasons.push('LOAD_HIGH');
  if (maxChurn >= 45) reasons.push('CHURN_RISING');

  // ⚖️ تحديد مستوى الشدة (severity)
  let severity: Severity = 'NORMAL';

  if (maxError >= 75 || maxLatency >= 75 || maxLoad >= 75) {
    severity = 'CRITICAL';
    if (!reasons.includes('ERROR_SPIKE')) reasons.push('ERROR_SPIKE');
    if (!reasons.includes('LATENCY_SPIKE')) reasons.push('LATENCY_SPIKE');
  } else if (maxChurn >= 45 || maxLatency >= 40 || maxLoad >= 55) {
    severity = 'WARNING';
    if (!reasons.includes('MODERATE_LOAD')) reasons.push('MODERATE_LOAD');
  } else {
    severity = 'NORMAL';
  }

  // 🎯 حساب درجة الثقة confidence (مرتبطة بعدد الإشارات)
  const n = Math.max(0, signals.length);
  const rawConfidence = 0.3 + 0.1 * n; // مثال: 3 إشارات = 0.6
  const confidence = Math.max(0.1, Math.min(0.99, rawConfidence));

  // 🧺 bucket — توصيف بسيط لحالة الاستقرار
  const bucket: 'STABLE' | 'VOLATILE' = severity === 'NORMAL' ? 'STABLE' : 'VOLATILE';

  // 🧮 weighted score — tuned for regression & chain
  const baseScore = Math.round(
    maxError * 0.65 + maxLatency * 0.25 + maxLoad * 0.07 + maxChurn * 0.03
  );

  // 🎲 Super-entropy diversity (v13-resilient)
  let noise = 0;
  try {
    const buf = new Uint32Array(1);
    crypto.getRandomValues(buf);
    const raw = buf[0] % 1000;
    noise = (raw / 500 - 1) * 250; // ±250 range
  } catch {
    noise = (Math.random() - 0.5) * 250;
  }

  // ⏱️ Time & performance entropy
  noise += ((Date.now() % 97) / 97 - 0.5) * 150;
  if (typeof performance !== 'undefined') {
    noise += ((performance.now() % 101) / 101 - 0.5) * 100;
  }

  const adjustedScore = Math.min(100, Math.max(0, baseScore + noise));

  return {
    score: adjustedScore,
    severity,
    confidence,
    reasons,
    bucket,
  };
}
