"""
Rule Engine für Alerts Agent.

Evaluiert Regeln gegen Alert-Items und führt Aktionen aus.
Batch-Verarbeitung und Action-Anwendung.
"""

import logging
from typing import List, Dict, Any, Optional

from alerts_agent.db.models import AlertItemDB, AlertRuleDB, RuleActionEnum

from .rule_models import (
    ConditionOperator,
    RuleCondition,
    RuleMatch,
    get_field_value,
    evaluate_condition,
    evaluate_rule,
    evaluate_rules_for_alert,
    create_keyword_rule,
    create_exclusion_rule,
    create_score_threshold_rule,
)

logger = logging.getLogger(__name__)

# Re-export for backward compatibility
__all__ = [
    "ConditionOperator",
    "RuleCondition",
    "RuleMatch",
    "get_field_value",
    "evaluate_condition",
    "evaluate_rule",
    "evaluate_rules_for_alert",
    "RuleEngine",
    "create_keyword_rule",
    "create_exclusion_rule",
    "create_score_threshold_rule",
]


class RuleEngine:
    """Rule Engine für Batch-Verarbeitung von Alerts."""

    def __init__(self, db_session):
        self.db = db_session
        self._rules_cache: Optional[List[AlertRuleDB]] = None

    def _get_active_rules(self) -> List[AlertRuleDB]:
        """Lädt aktive Regeln aus der Datenbank (cached)."""
        if self._rules_cache is None:
            from alerts_agent.db.repository import RuleRepository
            repo = RuleRepository(self.db)
            self._rules_cache = repo.get_active()
        return self._rules_cache

    def clear_cache(self) -> None:
        """Leert den Regel-Cache."""
        self._rules_cache = None

    def process_alert(self, alert: AlertItemDB) -> Optional[RuleMatch]:
        """Verarbeitet einen Alert mit allen aktiven Regeln."""
        rules = self._get_active_rules()
        return evaluate_rules_for_alert(alert, rules)

    def process_alerts(self, alerts: List[AlertItemDB]) -> Dict[str, RuleMatch]:
        """Verarbeitet mehrere Alerts mit allen aktiven Regeln."""
        rules = self._get_active_rules()
        results = {}

        for alert in alerts:
            match = evaluate_rules_for_alert(alert, rules)
            if match:
                results[alert.id] = match

        return results

    def apply_rule_actions(self, alert: AlertItemDB, match: RuleMatch) -> Dict[str, Any]:
        """Wendet die Regel-Aktion auf einen Alert an."""
        from alerts_agent.db.repository import AlertItemRepository, RuleRepository

        alert_repo = AlertItemRepository(self.db)
        rule_repo = RuleRepository(self.db)

        action = match.action
        config = match.action_config
        result = {"action": action.value, "success": False}

        try:
            if action == RuleActionEnum.KEEP:
                alert_repo.update_scoring(
                    alert_id=alert.id, score=1.0, decision="KEEP",
                    reasons=["rule_match"], summary=f"Matched rule: {match.rule_name}",
                    model="rule_engine",
                )
                result["success"] = True

            elif action == RuleActionEnum.DROP:
                alert_repo.update_scoring(
                    alert_id=alert.id, score=0.0, decision="DROP",
                    reasons=["rule_match"], summary=f"Dropped by rule: {match.rule_name}",
                    model="rule_engine",
                )
                result["success"] = True

            elif action == RuleActionEnum.TAG:
                tags = config.get("tags", [])
                if tags:
                    existing_tags = alert.user_tags or []
                    new_tags = list(set(existing_tags + tags))
                    alert_repo.update(alert.id, user_tags=new_tags)
                    result["tags_added"] = tags
                result["success"] = True

            elif action == RuleActionEnum.EMAIL:
                result["email_config"] = config
                result["success"] = True
                result["deferred"] = True

            elif action == RuleActionEnum.WEBHOOK:
                result["webhook_config"] = config
                result["success"] = True
                result["deferred"] = True

            elif action == RuleActionEnum.SLACK:
                result["slack_config"] = config
                result["success"] = True
                result["deferred"] = True

            rule_repo.increment_match_count(match.rule_id)

        except Exception as e:
            logger.error(f"Error applying rule action: {e}")
            result["error"] = str(e)

        return result
