"""دمج محرك VDE في وكيل الفرع.

VDE يملك كواشف **edge_model + vlm + الموديولات المرفوعة (OTA)** — مدفوعة بـ MQTT من
Frigate (motion/object/zone) + جدولة + بثّ. القواعد (منطقة/كثافة/عدّ) تبقى في الوكيل.

الحقن بالاعتماديات (لا يستورد agent) — الوكيل يمرّر دواله عند البناء.
"""
import os

from vde.api import Detector
from vde.builtins import FEATURE_DETECTORS, OnnxObject
from vde.engine import Engine, Services

# مفاتيح الميزات التي يستضيفها VDE (كي يتخطّاها منطق القواعد في الوكيل)
VDE_KEYS = set(FEATURE_DETECTORS)


class VlmTrigger(Detector):
    """يشغّل التحليل السحابي: يلتقط لقطات متتالية ويرسلها لـ/analyze؛ **السحابة** تحكم
    وتنشئ الحدث. VDE هنا مُشغِّل زمني فقط (لا يُصدر حدثاً على الحافة)."""
    kind = "vlm"

    def setup(self, ctx):
        self.n = int(ctx.config.get("frames", 4))
        self.gap = float(ctx.config.get("frame_gap_s", 0.4))

    def on_event(self, ev, ctx):
        frames = ctx.burst(ev.get("camera"), self.n, self.gap)
        if frames:
            ctx.vlm(self.key, frames)          # /analyze يحكم وينشئ الحدث سحابياً
        return None

    def on_frame(self, frame, ctx):
        ctx.vlm(self.key, [frame])
        return None


def build_engine(frame_fn, vlm_fn, log_fn, onnx_cls, emit_fn):
    """frame_fn(cam)->jpeg · vlm_fn(key,frames,cam)->verdict · emit_fn(key,cam,Detection)."""
    services = Services(frame_fn=frame_fn, vlm_fn=vlm_fn, log_fn=log_fn,
                        onnx_cls=onnx_cls)
    return Engine(services, emit_fn)


def _triggers_for(kind, cfg):
    if cfg.get("stream"):
        return ["stream"]                       # تحليل متّصل من البث المباشر
    if kind == "edge_model":
        return cfg.get("triggers") or ["motion"]
    return ["schedule"] if int(cfg.get("interval_min", 0)) > 0 else ["motion"]


def sync(engine, features, models_dir):
    """يعيد بناء كواشف VDE من الإعدادات الحالية (يُستدعى بعد كل تطبيق config)."""
    for key, cam in list(engine.slots):
        engine.unregister(key, cam)
    n = 0
    for f in features:
        kind, cfg = f["kind"], f.get("config", {})
        cam, key = cfg.get("camera"), f["key"]
        if not cam:
            continue
        if key in FEATURE_DETECTORS:            # مزايا VDE الخاصة (2026) بمفتاحها
            cls, trig_fn = FEATURE_DETECTORS[key]
            det, mpath, trig = cls(), None, trig_fn(cfg)
        elif kind == "edge_model":
            det = OnnxObject()
            det.interval_s = int(cfg.get("interval_s", 15))
            model = cfg.get("model")
            mpath = os.path.join(models_dir, model) if model else None
            trig = _triggers_for(kind, cfg)
        elif kind == "vlm":
            det = VlmTrigger()
            det.interval_s = int(cfg.get("interval_min", 0)) * 60
            mpath, trig = None, _triggers_for(kind, cfg)
        else:
            continue                            # القواعد التقليدية تبقى في الوكيل
        if engine.register(key, det, cam, cfg, mpath, 1, triggers=trig):
            n += 1
    return n
