/**
 * Phase 7 — Collective Feedback Protocol (CFP)
 * --------------------------------------------
 * تعريف شكل الرسائل بين العقد (Nodes) + أدوات بناء/تحقق الرسائل + أنماط intents.
 * خفيف، بدون تبعيات خارجية.
 */

export type CFPIntent =
  | 'SYNC_SNAPSHOT' // مزامنة التقارير/الحالة
  | 'SHARE_POLICY' // مشاركة سياسة/أوزان
  | 'REQUEST_ADVICE' // طلب نصيحة/اقتراح
  | 'BROADCAST_REPORT'; // بث تقرير (Evolution/Integration)

export interface CFPPayload {
  // أي محتوى منظّم؛ يُفضل أن يكون JSON قابل للتسلسل
  [key: string]: unknown;
}

export interface CFPMessage {
  id: string; // UUID/ULID (أو أي مولد معرفات) — هنا بنقبل أي ستـرنج
  ts: string; // ISO-8601 timestamp
  sourceId: string; // هوية العقدة المرسلة
  targetId?: string; // اختياري: العقدة المستهدفة (للـ direct)
  intent: CFPIntent;
  trust: number; // 0..1 تقدير الثقة في المرسل
  payload: CFPPayload; // الحمولة
  signature?: string; // اختياري: توقيع/هش للتوثيق (مستقبلاً)
  meta?: {
    replyTo?: string; // لو ده رد على رسالة
    correlationId?: string; // ربط سلاسل الرسائل
    tags?: string[]; // تصنيفات حرة
  };
}

export interface ValidationResult {
  valid: boolean;
  reason?: string;
}

export function nowISO(): string {
  return new Date().toISOString();
}

export function clamp01(x: number): number {
  if (!Number.isFinite(x)) return 0;
  return Math.max(0, Math.min(1, x));
}

/**
 * يبني رسالة CFP جاهزة للإرسال.
 */
export function buildMessage(
  intent: CFPIntent,
  payload: CFPPayload,
  opts: {
    id?: string;
    sourceId: string;
    targetId?: string;
    trust?: number; // default 0.7
    signature?: string;
    meta?: CFPMessage['meta'];
  }
): CFPMessage {
  return {
    id: opts.id ?? `cfp_${Math.random().toString(36).slice(2)}`,
    ts: nowISO(),
    sourceId: opts.sourceId,
    targetId: opts.targetId,
    intent,
    trust: clamp01(opts.trust ?? 0.7),
    payload,
    signature: opts.signature,
    meta: opts.meta,
  };
}

/**
 * تحقق بسيط من الرسالة (حقول رئيسية + مجال الثقة).
 * رجّع false مع سبب واضح لو ناقص حاجة مهمة.
 */
export function validateMessage(msg: CFPMessage): ValidationResult {
  if (!msg) return { valid: false, reason: 'Message is empty' };
  if (!msg.id) return { valid: false, reason: 'Missing id' };
  if (!msg.ts) return { valid: false, reason: 'Missing timestamp' };
  if (!msg.sourceId) return { valid: false, reason: 'Missing sourceId' };
  if (!msg.intent) return { valid: false, reason: 'Missing intent' };
  if (typeof msg.trust !== 'number') return { valid: false, reason: 'Missing trust' };
  const t = clamp01(msg.trust);
  if (t !== msg.trust) return { valid: false, reason: 'Invalid trust range' };
  if (typeof msg.payload !== 'object' || msg.payload == null) {
    return { valid: false, reason: 'Payload must be an object' };
  }
  return { valid: true };
}

/**
 * ميسرات سريعة بحسب الـ intent.
 */
export function isSync(msg: CFPMessage) {
  return msg.intent === 'SYNC_SNAPSHOT';
}
export function isPolicyShare(msg: CFPMessage) {
  return msg.intent === 'SHARE_POLICY';
}
export function isAdviceRequest(msg: CFPMessage) {
  return msg.intent === 'REQUEST_ADVICE';
}
export function isReportBroadcast(msg: CFPMessage) {
  return msg.intent === 'BROADCAST_REPORT';
}

/**
 * صحة بدائية للتوقيع — Placeholder (توسّع لاحقاً).
 */
export function verifySignature(_msg: CFPMessage): boolean {
  // لاحقاً: تحقق من signature باستخدام مفاتيح عامة
  return true;
}
