"""Summary-related entities for meeting summaries."""

from __future__ import annotations

from dataclasses import dataclass, field
from datetime import datetime
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from noteflow.domain.value_objects import MeetingId


@dataclass
class KeyPoint:
    """A key point extracted from the meeting.

    Evidence-linked to specific transcript segments for verification.
    """

    text: str
    segment_ids: list[int] = field(default_factory=list)
    start_time: float = 0.0
    end_time: float = 0.0
    position: int = 0  # Ordering within the summary

    # Database primary key (set after persistence)
    db_id: int | None = None

    def is_sourced(self) -> bool:
        """Check if key point is backed by transcript evidence."""
        return len(self.segment_ids) > 0


@dataclass
class ActionItem:
    """An action item extracted from the meeting.

    Evidence-linked to specific transcript segments for verification.
    """

    text: str
    assignee: str = ""
    due_date: datetime | None = None
    priority: int = 0  # 0=unspecified, 1=low, 2=medium, 3=high
    segment_ids: list[int] = field(default_factory=list)
    start_time: float = 0.0
    end_time: float = 0.0
    position: int = 0  # Ordering within the summary

    # Database primary key (set after persistence)
    db_id: int | None = None

    def has_evidence(self) -> bool:
        """Check if action item is backed by transcript evidence."""
        return len(self.segment_ids) > 0

    def is_assigned(self) -> bool:
        """Check if action item has a non-empty assignee."""
        assignee = self.assignee
        return bool(assignee and assignee.strip())

    def has_due_date(self) -> bool:
        """Check if action item has a due date."""
        return self.due_date is not None


@dataclass
class Summary:
    """Meeting summary entity.

    Contains executive summary, key points, and action items,
    all evidence-linked to transcript segments.
    """

    meeting_id: MeetingId
    executive_summary: str = ""
    key_points: list[KeyPoint] = field(default_factory=list)
    action_items: list[ActionItem] = field(default_factory=list)
    generated_at: datetime | None = None

    # Provider tracking
    provider_name: str = ""
    model_name: str = ""
    tokens_used: int | None = None
    latency_ms: float | None = None

    # Verification/citation metadata
    verification: dict[str, object] = field(default_factory=dict)

    # Database primary key (set after persistence)
    db_id: int | None = None

    def all_points_have_evidence(self) -> bool:
        """Check if all key points have transcript evidence."""
        points = self.key_points
        return all(kp.is_sourced() for kp in points) if points else True

    def all_actions_have_evidence(self) -> bool:
        """Check if all action items have transcript evidence."""
        actions = self.action_items
        return all(ai.has_evidence() for ai in actions) if actions else True

    def is_fully_evidenced(self) -> bool:
        """Check if entire summary is backed by transcript evidence."""
        return self.all_points_have_evidence() and self.all_actions_have_evidence()

    @property
    def key_point_count(self) -> int:
        """Number of key points in summary."""
        points = self.key_points
        return len(points)

    @property
    def action_item_count(self) -> int:
        """Number of action items in summary."""
        actions = self.action_items
        return len(actions)

    @property
    def unevidenced_points(self) -> list[KeyPoint]:
        """Key points without transcript evidence."""
        return [kp for kp in self.key_points if not kp.is_sourced()]

    @property
    def unevidenced_actions(self) -> list[ActionItem]:
        """Action items without transcript evidence."""
        return [ai for ai in self.action_items if not ai.has_evidence()]

    @property
    def model_version(self) -> str:
        """Backward-compatible model version string.

        Computes from provider_name and model_name for API compatibility.
        """
        if self.provider_name and self.model_name:
            return f"{self.provider_name}/{self.model_name}"
        return self.model_name or self.provider_name
