"""Reply and qualification event data models."""

from __future__ import annotations
from dataclasses import dataclass, field
from datetime import datetime
from typing import Optional
import uuid


# Intent categories for reply classification
INTENT_CATEGORIES = [
    "interested",      # Positive response, wants to learn more
    "not_now",         # Not interested right now, maybe later
    "objection",       # Has concerns or pushback
    "unsubscribe",     # Wants to be removed
    "out_of_office",   # Auto-reply, out of office
    "referral",        # Refers to someone else
    "meeting_request", # Wants to schedule a meeting
    "question",        # Has questions before committing
    "unknown",         # Could not classify
]

# Objection types
OBJECTION_TYPES = [
    "timing",          # Bad timing
    "budget",          # No budget
    "authority",       # Not the decision maker
    "need",            # No need / already solved
    "competitor",      # Using a competitor
    "internal",        # Building internally
]


@dataclass
class Reply:
    """
    Represents a reply received from a contact.
    """
    id: str = field(default_factory=lambda: str(uuid.uuid4()))
    sent_message_id: str = ""
    contact_id: str = ""

    # Content
    raw_text: str = ""
    subject: str = ""
    from_email: str = ""

    # Classification
    intent: str = "unknown"  # One of INTENT_CATEGORIES
    intent_confidence: float = 0.0
    objection_type: Optional[str] = None  # One of OBJECTION_TYPES if intent is "objection"
    sentiment: Optional[str] = None  # positive | neutral | negative

    # Extracted info
    meeting_requested: bool = False
    suggested_time: Optional[str] = None
    referral_name: Optional[str] = None
    referral_email: Optional[str] = None

    # Processing status
    processed: bool = False
    processed_at: Optional[datetime] = None
    processed_by: Optional[str] = None  # Agent codename or "manual"

    # Actions taken
    actions_taken: list[str] = field(default_factory=list)
    next_action: Optional[str] = None

    # Timestamps
    received_at: datetime = field(default_factory=datetime.now)
    created_at: datetime = field(default_factory=datetime.now)

    def to_dict(self) -> dict:
        return {
            "id": self.id,
            "sent_message_id": self.sent_message_id,
            "contact_id": self.contact_id,
            "raw_text": self.raw_text,
            "subject": self.subject,
            "from_email": self.from_email,
            "intent": self.intent,
            "intent_confidence": self.intent_confidence,
            "objection_type": self.objection_type,
            "sentiment": self.sentiment,
            "meeting_requested": self.meeting_requested,
            "suggested_time": self.suggested_time,
            "referral_name": self.referral_name,
            "referral_email": self.referral_email,
            "processed": self.processed,
            "processed_at": self.processed_at.isoformat() if self.processed_at else None,
            "processed_by": self.processed_by,
            "actions_taken": self.actions_taken,
            "next_action": self.next_action,
            "received_at": self.received_at.isoformat(),
            "created_at": self.created_at.isoformat(),
        }

    @classmethod
    def from_dict(cls, data: dict) -> Reply:
        data = data.copy()
        for field_name in ["processed_at", "received_at", "created_at"]:
            if field_name in data and isinstance(data[field_name], str):
                data[field_name] = datetime.fromisoformat(data[field_name])
        return cls(**data)

    def mark_processed(self, by: str, actions: list[str], next_action: str = None) -> None:
        """Mark reply as processed."""
        self.processed = True
        self.processed_at = datetime.now()
        self.processed_by = by
        self.actions_taken = actions
        self.next_action = next_action

    @property
    def is_positive(self) -> bool:
        """Check if reply is positive."""
        return self.intent in ("interested", "meeting_request", "question")

    @property
    def requires_dnc(self) -> bool:
        """Check if contact should be added to DNC."""
        return self.intent == "unsubscribe"


@dataclass
class QualificationEvent:
    """
    Represents a qualification status change for a contact.
    """
    id: str = field(default_factory=lambda: str(uuid.uuid4()))
    contact_id: str = ""

    # Event details
    event_type: str = "status_change"  # status_change | meeting_booked | handoff | note
    from_status: Optional[str] = None
    to_status: str = ""

    # Trigger info
    triggered_by: str = ""  # Agent codename or "manual"
    trigger_source: Optional[str] = None  # reply_id, etc.

    # Details
    notes: Optional[str] = None
    metadata: dict = field(default_factory=dict)

    # Timestamps
    created_at: datetime = field(default_factory=datetime.now)

    def to_dict(self) -> dict:
        return {
            "id": self.id,
            "contact_id": self.contact_id,
            "event_type": self.event_type,
            "from_status": self.from_status,
            "to_status": self.to_status,
            "triggered_by": self.triggered_by,
            "trigger_source": self.trigger_source,
            "notes": self.notes,
            "metadata": self.metadata,
            "created_at": self.created_at.isoformat(),
        }

    @classmethod
    def from_dict(cls, data: dict) -> QualificationEvent:
        data = data.copy()
        if "created_at" in data and isinstance(data["created_at"], str):
            data["created_at"] = datetime.fromisoformat(data["created_at"])
        return cls(**data)


@dataclass
class Segment:
    """
    Represents a segment/filter for contacts.
    """
    id: str = field(default_factory=lambda: str(uuid.uuid4()))
    name: str = ""
    description: Optional[str] = None

    # Filter criteria
    filters: dict = field(default_factory=dict)
    # Example filters:
    # {
    #     "industry": ["SaaS", "FinTech"],
    #     "employee_count_min": 50,
    #     "employee_count_max": 500,
    #     "icp_score_min": 70,
    #     "title_contains": ["VP", "Director", "Head"],
    #     "status": ["new", "contacted"],
    #     "tags": ["target_account"]
    # }

    # Stats
    contact_count: int = 0
    last_calculated_at: Optional[datetime] = None

    # Timestamps
    created_at: datetime = field(default_factory=datetime.now)
    updated_at: datetime = field(default_factory=datetime.now)

    def to_dict(self) -> dict:
        return {
            "id": self.id,
            "name": self.name,
            "description": self.description,
            "filters": self.filters,
            "contact_count": self.contact_count,
            "last_calculated_at": self.last_calculated_at.isoformat() if self.last_calculated_at else None,
            "created_at": self.created_at.isoformat(),
            "updated_at": self.updated_at.isoformat(),
        }

    @classmethod
    def from_dict(cls, data: dict) -> Segment:
        data = data.copy()
        for field_name in ["last_calculated_at", "created_at", "updated_at"]:
            if field_name in data and isinstance(data[field_name], str):
                data[field_name] = datetime.fromisoformat(data[field_name])
        return cls(**data)
