"""Session tracking for AITracer."""

from __future__ import annotations

import uuid
from dataclasses import dataclass, field
from datetime import datetime
from typing import TYPE_CHECKING, Any, Optional

if TYPE_CHECKING:
    from aitracer.client import AITracer


@dataclass
class Session:
    """
    Session for tracking user interactions over time.

    A session groups multiple logs/traces that belong to the same user interaction flow.

    Usage:
        with tracer.session(user_id="user-123") as session:
            response = client.chat.completions.create(...)
            session.event("user_action", data={"action": "clicked_button"})
            session.feedback(log_id="...", type="thumbs_up")

    Args:
        session_id: Unique session identifier
        user_id: App user ID - identifier for the end user of your application
                 (not the AITracer account user). This is stored as app_user_id in logs.
    """

    session_id: str
    # App user ID - identifier for the end user of the customer's application
    user_id: Optional[str] = None
    name: Optional[str] = None
    metadata: dict = field(default_factory=dict)

    # Internal
    _tracer: Optional["AITracer"] = field(default=None, repr=False)
    _started_at: datetime = field(default_factory=datetime.utcnow)
    _events: list[dict] = field(default_factory=list)
    _feedbacks: list[dict] = field(default_factory=list)
    _last_log_id: Optional[str] = field(default=None, repr=False)

    def set_metadata(self, key: str, value: Any) -> None:
        """Set a metadata value."""
        self.metadata[key] = value

    def event(
        self,
        event_type: str,
        *,
        name: Optional[str] = None,
        data: Optional[dict] = None,
        log_id: Optional[str] = None,
    ) -> None:
        """
        Record a custom event in the session.

        Args:
            event_type: Type of event (e.g., "message", "response", "tool_call", "error", "custom")
            name: Optional event name
            data: Optional event data
            log_id: Optional associated log ID
        """
        event = {
            "event_type": event_type,
            "name": name,
            "data": data or {},
            "log_id": log_id or self._last_log_id,
            "timestamp": datetime.utcnow().isoformat() + "Z",
        }
        self._events.append(event)

        # Send event immediately if tracer is available
        if self._tracer and self._tracer.enabled:
            self._tracer._send_session_event(self.session_id, event)

    def feedback(
        self,
        feedback_type: str,
        *,
        log_id: Optional[str] = None,
        score: Optional[int] = None,
        comment: Optional[str] = None,
    ) -> None:
        """
        Record user feedback for an AI response.

        Args:
            feedback_type: Type of feedback ("thumbs_up", "thumbs_down", "rating", "text")
            log_id: Log ID the feedback relates to. Defaults to last log in session.
            score: Numeric score (1-5 for rating, 1/-1 for thumbs)
            comment: Text comment
        """
        # Auto-set score for thumbs feedback
        if score is None:
            if feedback_type == "thumbs_up":
                score = 1
            elif feedback_type == "thumbs_down":
                score = -1

        feedback = {
            "feedback_type": feedback_type,
            "log_id": log_id or self._last_log_id,
            "score": score,
            "comment": comment,
            "user_id": self.user_id,
            "timestamp": datetime.utcnow().isoformat() + "Z",
        }
        self._feedbacks.append(feedback)

        # Send feedback immediately if tracer is available
        if self._tracer and self._tracer.enabled:
            self._tracer._send_feedback(self.session_id, feedback)

    def thumbs_up(self, log_id: Optional[str] = None, comment: Optional[str] = None) -> None:
        """Record a thumbs up feedback."""
        self.feedback("thumbs_up", log_id=log_id, comment=comment)

    def thumbs_down(self, log_id: Optional[str] = None, comment: Optional[str] = None) -> None:
        """Record a thumbs down feedback."""
        self.feedback("thumbs_down", log_id=log_id, comment=comment)

    def rate(self, score: int, log_id: Optional[str] = None, comment: Optional[str] = None) -> None:
        """
        Record a rating feedback (1-5).

        Args:
            score: Rating from 1 to 5
            log_id: Optional log ID
            comment: Optional comment
        """
        if not 1 <= score <= 5:
            raise ValueError("Score must be between 1 and 5")
        self.feedback("rating", log_id=log_id, score=score, comment=comment)

    def _set_last_log_id(self, log_id: str) -> None:
        """Internal: Set the last log ID for feedback association."""
        self._last_log_id = log_id
