"""قدرات 2026 السحابية — تنافس Verkada/Coram/Spot AI بالعربية:
  • nl_search      : بحث بلغة طبيعية عربية عبر أحداث الفرع (Conntour/Coram).
  • ops_brief      : مساعد Veedon — ملخّص تشغيلي سردي + توصيات (Spot AI/Ambient agents).
  • incident_timeline: تجميع أحداث متقاربة في "حادثة" واحدة (خط زمني موحّد).

الذكاء اختياري: Claude إن توفّر ANTHROPIC_API_KEY، وإلا بدائل قواعدية (تعمل بلا مفتاح).
"""
import json
import os
from datetime import timedelta

from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy import select
from sqlalchemy.orm import Session

from .db import get_db
from .models import Branch, Event, EventType, utcnow

router = APIRouter(prefix="/api/insights", tags=["insights"])


def _claude_json(system: str, user: str) -> dict | None:
    key = os.environ.get("ANTHROPIC_API_KEY")
    if not key:
        return None
    try:
        import anthropic
        m = anthropic.Anthropic(api_key=key).messages.create(
            model=os.environ.get("VEEDON_VLM_MODEL", "claude-opus-4-8"),
            max_tokens=700, system=system,
            messages=[{"role": "user", "content": user}])
        txt = "".join(b.text for b in m.content if b.type == "text")
        s, e = txt.find("{"), txt.rfind("}")
        return json.loads(txt[s:e + 1]) if s != -1 else None
    except Exception:
        return None


def _claude_text(system: str, user: str) -> str | None:
    key = os.environ.get("ANTHROPIC_API_KEY")
    if not key:
        return None
    try:
        import anthropic
        m = anthropic.Anthropic(api_key=key).messages.create(
            model=os.environ.get("VEEDON_VLM_MODEL", "claude-opus-4-8"),
            max_tokens=900, system=system,
            messages=[{"role": "user", "content": user}])
        return "".join(b.text for b in m.content if b.type == "text").strip()
    except Exception:
        return None


def nl_to_filter(query: str, names: dict) -> dict:
    """يحوّل استعلاماً عربياً إلى فلتر مُهيكل. Claude إن توفّر، وإلا مطابقة كلمات."""
    keys = list(names.keys())
    got = _claude_json(
        "حوّل استعلام مراقبة عربياً إلى فلتر JSON فقط بالشكل: "
        '{"feature_keys":[],"since_hours":168,"severity":"any"}. '
        f"المفاتيح المتاحة وأسماؤها: {json.dumps(names, ensure_ascii=False)}",
        query)
    if got:
        return {"feature_keys": got.get("feature_keys") or [],
                "since_hours": int(got.get("since_hours") or 168),
                "severity": got.get("severity") or "any"}
    # بديل قواعدي: طابق أي كلمة من اسم الميزة + كلمات زمن شائعة
    q = query
    fk = [k for k, ar in names.items()
          if ar and any(len(w) > 2 and w in q for w in ar.split())]
    hours = 24 if "اليوم" in q or "أمس" in q else (168 if "أسبوع" in q else 720)
    sev = "high" if ("مخالف" in q or "خطر" in q) else "any"
    return {"feature_keys": fk, "since_hours": hours, "severity": sev}


def _events_for(db, branch, since_hours, feature_keys=None, severity="any"):
    since = utcnow() - timedelta(hours=since_hours)
    cam_ids = [c.id for c in branch.cameras]
    if not cam_ids:
        return []
    stmt = select(Event).where(Event.camera_id.in_(cam_ids),
                               Event.detected_at >= since)
    if feature_keys:
        stmt = stmt.where(Event.event_type.in_(feature_keys))
    if severity != "any":
        stmt = stmt.where(Event.severity == severity)
    return db.scalars(stmt.order_by(Event.detected_at.desc()).limit(200)).all()


def _feature_names(db):
    return {et.feature_key: et.name_ar for et in db.scalars(select(EventType)).all()
            if et.feature_key}


@router.post("/search")
def nl_search(payload: dict, db: Session = Depends(get_db)):
    """بحث بلغة طبيعية عربية: {branch_id, query} → أحداث مطابقة + الفلتر المُستنتج."""
    branch = db.get(Branch, payload.get("branch_id"))
    if not branch:
        raise HTTPException(404, "branch not found")
    names = _feature_names(db)
    flt = nl_to_filter(payload.get("query", ""), names)
    evs = _events_for(db, branch, flt["since_hours"],
                      flt["feature_keys"] or None, flt["severity"])
    return {"filter": flt,
            "count": len(evs),
            "results": [{"id": str(e.id), "type": e.event_type,
                         "name": names.get(e.event_type, e.event_type),
                         "severity": e.severity,
                         "at": e.detected_at.isoformat() if e.detected_at else None,
                         "snapshot_url": e.snapshot_url,
                         "note": (e.meta or {}).get("ai_note", "")} for e in evs]}


@router.get("/brief/branch/{branch_id}")
def ops_brief(branch_id: str, days: int = 7, db: Session = Depends(get_db)):
    """مساعد Veedon: ملخّص تشغيلي سردي عربي + توصيات لأحداث الفرع."""
    branch = db.get(Branch, branch_id)
    if not branch:
        raise HTTPException(404, "branch not found")
    names = _feature_names(db)
    evs = _events_for(db, branch, days * 24)
    counts, viol = {}, 0
    for e in evs:
        counts[e.event_type] = counts.get(e.event_type, 0) + 1
        if e.severity == "high":
            viol += 1
    top = sorted(counts.items(), key=lambda kv: -kv[1])[:8]
    facts = "؛ ".join(f"{names.get(k, k)}: {v}" for k, v in top) or "لا أحداث"
    org = branch.organization.name if branch.organization else "—"
    narrative = _claude_text(
        "أنت مساعد عمليات ذكي. اكتب ملخّصاً تشغيلياً عربياً موجزاً (3–5 جُمل) + 3 توصيات "
        "عملية بنقاط، من إحصاء أحداث المراقبة. لا تُبالغ ولا تختلق.",
        f"الفرع: {org} — {branch.name}. الفترة: {days} يوماً. إجمالي الأحداث "
        f"{len(evs)} منها {viol} مخالفة. التوزيع: {facts}.")
    if not narrative:                              # بديل قالبي (بلا مفتاح)
        narrative = (f"خلال آخر {days} يوماً رُصد {len(evs)} حدثاً ({viol} مخالفة) في "
                     f"{org} — {branch.name}. الأبرز: {facts}.\n"
                     "توصيات:\n- راجع المخالفات عالية الخطورة أولاً.\n"
                     "- عايِر الكاميرات كثيرة الإنذارات.\n- فعّل تنبيهات مركّبة للحالات الحرجة.")
    return {"branch": branch.name, "days": days, "total": len(evs),
            "violations": viol, "top": top, "brief": narrative}


def group_incidents(events, names, window_s=120):
    """تجميع أحداث متقاربة (نفس الكاميرا، ضمن نافذة) في حوادث — خط زمني موحّد."""
    incidents = []
    for e in sorted(events, key=lambda x: (x.camera_id or "",
                                           x.detected_at or utcnow())):
        cur = incidents[-1] if incidents else None
        if (cur and cur["camera_id"] == e.camera_id and e.detected_at
                and cur["_last"] and (e.detected_at - cur["_last"]).total_seconds()
                <= window_s):
            cur["events"].append(e.event_type)
            cur["_last"] = e.detected_at
            cur["severity"] = "high" if e.severity == "high" else cur["severity"]
        else:
            incidents.append({"camera_id": str(e.camera_id), "_last": e.detected_at,
                              "start": e.detected_at, "severity": e.severity,
                              "events": [e.event_type],
                              "snapshot_url": e.snapshot_url})
    for inc in incidents:                          # صياغة نهائية
        inc["labels"] = [names.get(k, k) for k in inc["events"]]
        inc["start"] = inc["start"].isoformat() if inc["start"] else None
        inc.pop("_last", None)
    return incidents


@router.get("/incidents/branch/{branch_id}")
def incidents(branch_id: str, hours: int = 24, db: Session = Depends(get_db)):
    """خط زمني موحّد: يجمع أحداث الفرع المتقاربة في حوادث."""
    branch = db.get(Branch, branch_id)
    if not branch:
        raise HTTPException(404, "branch not found")
    names = _feature_names(db)
    evs = _events_for(db, branch, hours)
    inc = group_incidents(evs, names)
    return {"count": len(inc), "incidents": inc}
