"""
meca.py
=======

מנוע היגיון סמלי.
אופציונלית מתוגבר ע"י סינתיה לתכנון והסבר.
"""

from typing import Any, Dict, List, Set, Optional
import logging
from .mycelium import מיצליום
from .synthia import סינתיה

logger = logging.getLogger(__name__)


class מקה:
    def __init__(self, מופע: str, סינתיה_: Optional[סינתיה] = None):
        self.ליבה = מיצליום.קבל(מופע)
        self.core = self.ליבה  # תאימות אנגלית
        self.סינתיה = סינתיה_
        self.synthia = self.סינתיה  # תאימות אנגלית

        # טעינת סמלים מאחסון מתמיד
        self.סמלים: Dict[str, int] = self._טען_סמלים()
        self.symbols = self.סמלים  # תאימות אנגלית
        self.דפוסים: Dict[str, Set[int]] = {}
        self.patterns = self.דפוסים  # תאימות אנגלית
        self.עקבה_אחרונה: Dict[str, Any] = {}
        self.last_trace = self.עקבה_אחרונה  # תאימות אנגלית

    # ---------- התמדה של סמלים ----------

    def _טען_סמלים(self) -> Dict[str, int]:
        """טען מיפוי סמלים מאחסון מתמיד."""
        try:
            אינדקס_סמלים = self.ליבה.זיכרון.קרא(0) if self.ליבה.זיכרון.גודל() > 0 else None
            if אינדקס_סמלים and isinstance(אינדקס_סמלים, dict) and "__symbols__" in str(אינדקס_סמלים):
                return אינדקס_סמלים.get("data", {})
        except Exception:
            pass
        return {}

    def _שמור_סמלים(self):
        """שמור מיפוי סמלים באחסון מתמיד."""
        try:
            נתוני_סמלים = {"__symbols__": True, "data": self.סמלים}
            if self.ליבה.זיכרון.גודל() > 0:
                self.ליבה.זיכרון.כתוב(0, נתוני_סמלים)
            else:
                self.ליבה.זיכרון.הקצה(נתוני_סמלים)
        except Exception:
            logger.exception("[Meca] Failed to save symbols")

    # ---------- עובדות ----------

    def עובדה(self, ערך: Any, סמל: Optional[str] = None) -> int:
        אינדקס = self.ליבה.עובדה(ערך)
        if סמל:
            self.סמלים[סמל] = אינדקס
            self._שמור_סמלים()
        return אינדקס

    def fact(self, value: Any, symbol: Optional[str] = None) -> int:
        return self.עובדה(value, symbol)

    def היזכר(self, אינדקס: int) -> Any:
        return self.ליבה.היזכר(אינדקס)

    def recall(self, idx: int) -> Any:
        return self.היזכר(idx)

    # ---------- אילוצים ----------

    def תייג(self, ציר: int, עובדה_: int):
        self.ליבה.מגבלות.צרף(ציר, עובדה_)

    def tag(self, axis: int, fact: int):
        return self.תייג(axis, fact)

    def חיתוך(self, צירים: List[int]) -> Set[int]:
        תוצאה = self.ליבה.מגבלות.חיתוך(צירים)
        self.עקבה_אחרונה = {"op": "intersect", "axes": צירים, "result": תוצאה}
        self.last_trace = self.עקבה_אחרונה
        return תוצאה

    def intersect(self, axes: List[int]) -> Set[int]:
        return self.חיתוך(axes)

    # ---------- הסבר מבוסס LLM ----------

    def הסבר_אחרון(self) -> Optional[str]:
        if not self.סינתיה or not self.עקבה_אחרונה:
            return None

        return self.סינתיה.שיחה(
            f"Explain this reasoning trace:\n{self.עקבה_אחרונה}",
            מערכת="You are a reasoning analyst.",
        )

    def explain_last(self) -> Optional[str]:
        return self.הסבר_אחרון()


# תאימות שמות
Meca = מקה
