"""Contact data model - represents a person at an account."""

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


@dataclass
class Contact:
    """
    Represents a person/contact at a company being prospected.
    """
    id: str = field(default_factory=lambda: str(uuid.uuid4()))
    account_id: str = ""
    email: str = ""
    first_name: str = ""
    last_name: str = ""
    title: Optional[str] = None
    department: Optional[str] = None
    phone: Optional[str] = None
    linkedin_url: Optional[str] = None
    persona: Optional[str] = None  # e.g., "decision_maker", "influencer", "champion"
    seniority: Optional[str] = None  # e.g., "c_level", "vp", "director", "manager", "ic"
    icp_score: int = 0

    # Status flags
    dnc: bool = False  # Do not contact
    dnc_reason: Optional[str] = None
    bounced: bool = False
    unsubscribed: bool = False

    # Engagement tracking
    status: str = "new"  # new, contacted, engaged, qualified, disqualified
    last_contacted_at: Optional[datetime] = None
    last_replied_at: Optional[datetime] = None
    reply_count: int = 0

    # Enrichment
    enrichment_data: dict = field(default_factory=dict)
    tags: list[str] = field(default_factory=list)

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

    @property
    def full_name(self) -> str:
        """Return full name."""
        return f"{self.first_name} {self.last_name}".strip()

    @property
    def can_contact(self) -> bool:
        """Check if contact can be emailed."""
        return not (self.dnc or self.bounced or self.unsubscribed)

    def to_dict(self) -> dict:
        """Convert to dictionary for JSON serialization."""
        return {
            "id": self.id,
            "account_id": self.account_id,
            "email": self.email,
            "first_name": self.first_name,
            "last_name": self.last_name,
            "title": self.title,
            "department": self.department,
            "phone": self.phone,
            "linkedin_url": self.linkedin_url,
            "persona": self.persona,
            "seniority": self.seniority,
            "icp_score": self.icp_score,
            "dnc": self.dnc,
            "dnc_reason": self.dnc_reason,
            "bounced": self.bounced,
            "unsubscribed": self.unsubscribed,
            "status": self.status,
            "last_contacted_at": self.last_contacted_at.isoformat() if self.last_contacted_at else None,
            "last_replied_at": self.last_replied_at.isoformat() if self.last_replied_at else None,
            "reply_count": self.reply_count,
            "enrichment_data": self.enrichment_data,
            "tags": self.tags,
            "created_at": self.created_at.isoformat(),
            "updated_at": self.updated_at.isoformat(),
        }

    @classmethod
    def from_dict(cls, data: dict) -> Contact:
        """Create Contact from dictionary."""
        data = data.copy()
        for field_name in ["created_at", "updated_at", "last_contacted_at", "last_replied_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_dnc(self, reason: str) -> None:
        """Mark contact as do-not-contact."""
        self.dnc = True
        self.dnc_reason = reason
        self.updated_at = datetime.now()

    def mark_bounced(self) -> None:
        """Mark email as bounced."""
        self.bounced = True
        self.updated_at = datetime.now()

    def mark_unsubscribed(self) -> None:
        """Mark as unsubscribed."""
        self.unsubscribed = True
        self.updated_at = datetime.now()

    def record_contact(self) -> None:
        """Record that contact was reached out to."""
        self.last_contacted_at = datetime.now()
        if self.status == "new":
            self.status = "contacted"
        self.updated_at = datetime.now()

    def record_reply(self) -> None:
        """Record a reply from contact."""
        self.last_replied_at = datetime.now()
        self.reply_count += 1
        if self.status in ("new", "contacted"):
            self.status = "engaged"
        self.updated_at = datetime.now()
