from datetime import datetime
from typing import Optional, Union, Any

from analogai.foundation.modules.shared.statement_base import StatementBase
from analogai.foundation.modules.shared.statement_validator import validate_probability_validity
from analogai.foundation.modules.notion.notion import Notion
from analogai.foundation.core.value_objects.modifier import Modifier
from analogai.foundation.core.value_objects.relation import Relation
from analogai.foundation.common.utils.entity_formatters import (
    format_direct_statement_repr,
)


class DirectStatement(StatementBase):
    def __init__(
        self,
        user_id: str,
        agent_id: str,
        subject_notion: Notion,
        relation: Relation,
        complement_notion: Notion,
        id: Optional[str] = None,
        modifier: Optional[Modifier] = None,
        probability: Union[float, int] = 1.0,
        validity: Union[float, int] = 1.0,
        created_at: Optional[datetime] = None,
    ):
        if not user_id:
            raise ValueError("user_id must be a non-empty string")
        validate_probability_validity(probability, validity)
        super().__init__(
            agent_id=agent_id,
            subject_notion=subject_notion,
            complement_notion=complement_notion,
            relation=relation,
            id=id,
            modifier=modifier,
        )
        self.user_id = user_id
        self._probability = float(probability)
        self._validity = float(validity)
        self.created_at = created_at if created_at else datetime.now()

    @property
    def probability(self) -> float:
        return self._probability

    @probability.setter
    def probability(self, value: Union[float, int]) -> None:
        validate_probability_validity(value, self._validity)
        self._probability = float(value)

    @property
    def validity(self) -> float:
        return self._validity

    @validity.setter
    def validity(self, value: Union[float, int]) -> None:
        validate_probability_validity(self._probability, value)
        self._validity = float(value)

    def visit(self, visitor: Any) -> Any:
        return visitor.visit_statement(self)


    def __str__(self) -> str:
        return format_direct_statement_repr(self)

    def __repr__(self) -> str:
        return format_direct_statement_repr(self)


Statement = DirectStatement