"""
synthia.py
==========

סינתיה היא מנוע LLM מאובטח ומולטי-מודלי.
היא מטפלת בכל קריאות ה-API והאינטראקציות עם מודלים.
"""

import base64
import io
import hashlib as hs
import requests
from typing import Any, Dict, Optional
from PIL import Image

# ============================================================
# תצורת אבטחה (לוגיקה ללא שינוי)
# ============================================================


class תצורת_אבטחה:
    _תצורה_מוצפנת = {
        "api_base": "gd2DbELGj9OwKd5YOKBCOIC1f4qM+qDSTXYK9hC+mNvG38Y=",
        "models": {
            "text": "jsaYe12Zj5u8KsdccuAOdYe2d44=",
            "vision": "jsaYe12Zj5u8KsdccuFNYYCvfNeMoA==",
        },
        "keys": [
            "h9+WbFjRwZGKJtsPbuBpP9btb7Cmvb/UVCAX4l+lvdmcwbkqCNH0xI4Ww3k1ilMJhvZLuYqhpd1MRDnbepSC17zawklphA==",
            "h9+WbFjR2a2BFO4QFLFLJdXLK6mGgYfeb0gF+2aPtvq76qFsBazhzOtq2lQPimYLgtRwz9a3odJSTRDEDZmY49zDgl8FmQ==",
        ],
    }

    @staticmethod
    def פענח(מפתח_אבטחה: str) -> Dict[str, Any]:
        מפתח = hs.sha256(מפתח_אבטחה.encode()).digest()

        def פענח_בתים(ב: bytes) -> str:
            מפתח_מורחב = מפתח * (len(ב) // len(מפתח) + 1)
            return bytes(x ^ מפתח_מורחב[i] for i, x in enumerate(ב)).decode()

        def ב64(x):
            return base64.b64decode(x)

        return {
            "api_base": פענח_בתים(ב64(תצורת_אבטחה._תצורה_מוצפנת["api_base"])),
            "models": {
                k: פענח_בתים(ב64(v))
                for k, v in תצורת_אבטחה._תצורה_מוצפנת["models"].items()
            },
            "keys": [פענח_בתים(ב64(k)) for k in תצורת_אבטחה._תצורה_מוצפנת["keys"]],
        }


# ============================================================
# ליבת סינתיה
# ============================================================


class סינתיה:
    """
    מנוע LLM מאובטח ומולטי-מודלי.
    """

    def __init__(self, מפתח_אבטחה: str, **kwargs):
        if "security_key" in kwargs:
            מפתח_אבטחה = kwargs["security_key"]
        self._תצורה = תצורת_אבטחה.פענח(מפתח_אבטחה)
        self._קריאות = 0
        self._אסימונים = 0

    # ---------------- מאפייני תאימות ----------------

    @property
    def תצורה(self) -> Dict[str, Any]:
        return self._תצורה

    @property
    def config(self) -> Dict[str, Any]:
        return self._תצורה

    @config.setter
    def config(self, ערך: Dict[str, Any]):
        self._תצורה = ערך

    @property
    def קריאות(self) -> int:
        return self._קריאות

    @property
    def calls(self) -> int:
        return self._קריאות

    @calls.setter
    def calls(self, ערך: int):
        self._קריאות = ערך

    @property
    def אסימונים(self) -> int:
        return self._אסימונים

    @property
    def tokens(self) -> int:
        return self._אסימונים

    @tokens.setter
    def tokens(self, ערך: int):
        self._אסימונים = ערך

    # ---------------- פנימי ----------------

    def _מפתח(self) -> str:
        return self._תצורה["keys"][self._קריאות % len(self._תצורה["keys"])]

    def _בקשה(self, מטען: Dict, סוג_מודל: str) -> Dict:
        self._קריאות += 1

        מטען["model"] = self._תצורה["models"][סוג_מודל]

        תגובה = requests.post(
            f"{self._תצורה['api_base']}/chat/completions",
            headers={
                "Authorization": f"Bearer {self._מפתח()}",
                "Content-Type": "application/json",
            },
            json=מטען,
            timeout=120,
        )

        if תגובה.status_code != 200:
            raise RuntimeError(תגובה.text)

        נתונים = תגובה.json()
        self._אסימונים += נתונים.get("usage", {}).get("total_tokens", 0)
        return נתונים

    # ---------------- API ציבורי ----------------

    def שיחה(self, הודעה: str, מערכת: Optional[str] = None) -> str:
        """
        שיחה עם LLM.

        הערה:
        ה-backend אינו תומך בתפקיד system.
        הוראות מערכת מוזרקות בבטחה לתוך ההודעה.
        """

        if מערכת:
            משולב = (
                f"[SYSTEM INSTRUCTIONS]\n"
                f"{מערכת}\n\n"
                f"[USER INPUT]\n"
                f"{הודעה}"
            )
        else:
            משולב = הודעה

        תוצאה = self._בקשה(
            {
                "messages": [
                    {"role": "user", "content": משולב}
                ],
                "temperature": 0.6,
                "max_tokens": 4096,
            },
            "text",
        )

        return תוצאה["choices"][0]["message"]["content"]

    def נתח_תמונה(self, תמונה: Image.Image, הנחיה: str) -> str:
        מאגר = io.BytesIO()
        תמונה.save(מאגר, format="JPEG")
        ב64 = base64.b64encode(מאגר.getvalue()).decode()

        תוצאה = self._בקשה(
            {
                "messages": [{
                    "role": "user",
                    "content": [
                        {"type": "text", "text": הנחיה},
                        {"type": "image_url",
                         "image_url": {"url": f"data:image/jpeg;base64,{ב64}"}},
                    ],
                }],
                "temperature": 0.4,
                "max_tokens": 1024,
            },
            "vision",
        )
        return תוצאה["choices"][0]["message"]["content"]

    def סטטיסטיקות(self) -> Dict[str, int]:
        return {"calls": self._קריאות, "tokens": self._אסימונים}

    def השלם(self, הנחיה: str) -> str:
        """
        ממשק השלמה טקסטואלי פשוט.
        """
        תגובה = self.שיחה(הנחיה)
        return תגובה.strip()

    # ---------------- תאימות אנגלית ----------------

    def chat(self, message: str, system: Optional[str] = None) -> str:
        return self.שיחה(message, system)

    def analyze_image(self, image: Image.Image, prompt: str) -> str:
        return self.נתח_תמונה(image, prompt)

    def stats(self) -> Dict[str, int]:
        return self.סטטיסטיקות()

    def complete(self, prompt: str) -> str:
        return self.השלם(prompt)


# תאימות שמות
Synthia = סינתיה
SecureConfig = תצורת_אבטחה
