"""Rule model classes for simple and conditional rules.

Provides a progression path from static values (MVP) to conditional
expressions (Sprint 22+) to natural language rules (future).
"""

from __future__ import annotations

from dataclasses import dataclass, field
from enum import Enum


class RuleMode(Enum):
    """How a rule is specified.

    SIMPLE: Static key-value configuration (MVP).
    CONDITIONAL: If-then conditions with expressions.
    EXPRESSION: Full expression language (future).
    NATURAL: Natural language transformed to expression (future).
    """

    SIMPLE = "simple"
    CONDITIONAL = "conditional"
    EXPRESSION = "expression"
    NATURAL = "natural"


@dataclass
class RuleAction:
    """Action to take when a rule matches.

    Actions are executed by the appropriate service when a rule
    condition evaluates to true.

    Attributes:
        action_type: Type of action (e.g., "set_value", "notify", "auto_start").
        params: Action-specific parameters.
    """

    action_type: str
    params: dict[str, object] = field(default_factory=dict)


@dataclass
class ConditionalRule:
    """A rule with a condition and actions.

    Supports multiple modes of condition specification, from simple
    static configuration to full expression evaluation.

    Attributes:
        name: Human-readable rule name.
        mode: How the condition is interpreted.
        condition: The condition (interpretation depends on mode).
        actions: Actions to execute when condition matches.
        priority: Priority for conflict resolution (higher = evaluated first).
        enabled: Whether this rule is active.
        metadata: Additional metadata for UI/debugging.

    Example (SIMPLE mode):
        ConditionalRule(
            name="Default export settings",
            mode=RuleMode.SIMPLE,
            actions=[RuleAction("set_value", {"format": "markdown"})],
        )

    Example (CONDITIONAL mode):
        ConditionalRule(
            name="Auto-start standups",
            mode=RuleMode.CONDITIONAL,
            condition="meeting.title contains 'standup'",
            actions=[RuleAction("auto_start", {"notify": True})],
            priority=10,
        )
    """

    name: str
    mode: RuleMode = RuleMode.SIMPLE
    condition: str | None = None
    actions: list[RuleAction] = field(default_factory=list)
    priority: int = 0
    enabled: bool = True
    metadata: dict[str, object] = field(default_factory=dict)

    def is_simple(self) -> bool:
        """Check if this is a simple (no-condition) rule.

        Returns:
            True if mode is SIMPLE.
        """
        return self.mode == RuleMode.SIMPLE

    def is_conditional(self) -> bool:
        """Check if this rule has a condition.

        Returns:
            True if mode is CONDITIONAL, EXPRESSION, or NATURAL.
        """
        return self.mode in (RuleMode.CONDITIONAL, RuleMode.EXPRESSION, RuleMode.NATURAL)

    def get_metadata(self, key: str, default: object = None) -> object:
        """Retrieve rule metadata.

        Args:
            key: Metadata key.
            default: Value if key not found.

        Returns:
            The metadata value or default.
        """
        return self.metadata.get(key, default)


@dataclass
class RuleSet:
    """Collection of rules for a rule type.

    Provides both simple static defaults and conditional rules,
    supporting progressive enhancement from MVP to advanced rules.

    Attributes:
        rule_type: The rule type name (e.g., "trigger", "export").
        rules: List of conditional rules (evaluated in priority order).
        simple_defaults: Static defaults when no conditional rules match.

    Example (simple mode only):
        RuleSet(
            rule_type="export",
            simple_defaults={"format": "markdown", "include_timestamps": True},
        )

    Example (with conditional rules):
        RuleSet(
            rule_type="trigger",
            rules=[
                ConditionalRule(
                    name="Auto-start standups",
                    mode=RuleMode.CONDITIONAL,
                    condition="meeting.title contains 'standup'",
                    actions=[RuleAction("auto_start", {})],
                ),
            ],
            simple_defaults={"auto_start_enabled": False},
        )
    """

    rule_type: str
    rules: list[ConditionalRule] = field(default_factory=list)
    simple_defaults: dict[str, object] = field(default_factory=dict)

    def is_simple_mode(self) -> bool:
        """Check if using simple static defaults only.

        Returns:
            True if no conditional rules defined.
        """
        return len(self.rules) == 0 and len(self.simple_defaults) > 0

    def add_rule(self, rule: ConditionalRule) -> None:
        """Add a rule to the set.

        Args:
            rule: The rule to add.
        """
        self.rules.append(rule)

    def remove_rule(self, name: str) -> bool:
        """Remove a rule by name.

        Args:
            name: The rule name to remove.

        Returns:
            True if a rule was removed.
        """
        original_count = len(self.rules)
        self.rules = [r for r in self.rules if r.name != name]
        return len(self.rules) < original_count
