"""Composite termination condition for AND/OR logic."""

from typing import List, Literal, Optional, Sequence

from agentbyte.messages import Message
from agentbyte.types import StopMessage

from .base import BaseTermination


class CompositeTermination(BaseTermination):
    """
    Combines multiple termination conditions with AND/OR logic.

    Modes:
        - "any": Terminates when ANY condition is met (OR logic)
        - "all": Terminates when ALL conditions are met (AND logic)

    Example:
        # Stop after 10 messages OR when "DONE" appears
        termination = MaxMessageTermination(10) | TextMentionTermination("DONE")

        # Stop only when BOTH 5 messages AND "APPROVED" appears
        termination = MaxMessageTermination(5) & TextMentionTermination("APPROVED")

        # Complex nested conditions
        termination = (
            (MaxMessageTermination(20) | TextMentionTermination("DONE"))
            & TimeoutTermination(300)
        )
    """

    def __init__(
        self,
        conditions: List[BaseTermination],
        mode: Literal["any", "all"] = "any",
    ):
        super().__init__()
        if not conditions:
            raise ValueError("At least one condition is required")
        if len(conditions) < 2:
            raise ValueError("Composite termination requires at least 2 conditions")
        self.conditions = conditions
        self.mode = mode

    def check(self, new_messages: Sequence[Message]) -> Optional[StopMessage]:
        """Check all conditions according to mode."""
        for condition in self.conditions:
            condition.check(new_messages)

        met_conditions = [c for c in self.conditions if c.is_met()]

        if self.mode == "any" and met_conditions:
            # Any condition met
            first_met = met_conditions[0]
            return self._set_termination(
                first_met.get_reason(),
                {
                    "mode": "any",
                    "met_conditions": len(met_conditions),
                    "total_conditions": len(self.conditions),
                    "triggered_by": first_met.__class__.__name__,
                },
            )
        elif self.mode == "all" and len(met_conditions) == len(self.conditions):
            # All conditions met
            reasons = [c.get_reason() for c in self.conditions]
            return self._set_termination(
                f"All conditions met: {'; '.join(reasons)}",
                {
                    "mode": "all",
                    "met_conditions": len(met_conditions),
                    "total_conditions": len(self.conditions),
                    "all_reasons": reasons,
                },
            )

        return None

    def reset(self) -> None:
        """Reset all child conditions."""
        super().reset()
        for condition in self.conditions:
            condition.reset()
