"""
Base constraint classes for query decomposition.
"""

from dataclasses import dataclass
from enum import Enum
from typing import Any, Dict, Optional


class ConstraintType(Enum):
    """Types of constraints in queries."""

    PROPERTY = "property"  # e.g., "formed during ice age"
    NAME_PATTERN = "name_pattern"  # e.g., "contains body part"
    EVENT = "event"  # e.g., "fall between 2000-2021"
    STATISTIC = "statistic"  # e.g., "84.5x ratio"
    TEMPORAL = "temporal"  # e.g., "in 2014"
    LOCATION = "location"  # e.g., "in Colorado"
    COMPARISON = "comparison"  # e.g., "more than X"
    EXISTENCE = "existence"  # e.g., "has a viewpoint"


@dataclass
class Constraint:
    """A single constraint extracted from a query."""

    id: str
    type: ConstraintType
    description: str
    value: Any
    weight: float = 1.0  # Importance of this constraint
    metadata: Optional[Dict[str, Any]] = None

    def __post_init__(self):
        """Initialize metadata if not provided."""
        if self.metadata is None:
            self.metadata = {}

    def to_search_terms(self) -> str:
        """Convert constraint to search terms."""
        if self.type == ConstraintType.PROPERTY:
            return self.value
        if self.type == ConstraintType.NAME_PATTERN:
            return f"{self.value} name trail mountain"
        if self.type == ConstraintType.EVENT:
            return f"{self.value} accident incident"
        if self.type == ConstraintType.STATISTIC:
            return f"{self.value} statistics data"
        return str(self.value)

    def is_critical(self) -> bool:
        """Determine if this is a critical constraint that must be satisfied."""
        # Consider NAME_PATTERN constraints as critical regardless of weight
        if self.type == ConstraintType.NAME_PATTERN:
            return True
        # Otherwise use weight to determine criticality
        return self.weight > 0.8
