"""
Slack models with self-parsing from Slack API responses.
"""

from pydantic import BaseModel
from typing import Optional, List
from datetime import datetime


class User(BaseModel):
    id: str
    name: str
    real_name: Optional[str] = None
    display_name: Optional[str] = None
    is_bot: bool = False

    @classmethod
    def from_slack(cls, user: dict) -> "User":
        profile = user.get("profile", {})
        return cls(
            id=user["id"],
            name=user.get("name", ""),
            real_name=profile.get("real_name") or user.get("real_name"),
            display_name=profile.get("display_name"),
            is_bot=user.get("is_bot", False),
        )


class Channel(BaseModel):
    id: str
    name: str
    is_private: bool = False
    is_archived: bool = False
    is_member: bool = False
    topic: Optional[str] = None
    purpose: Optional[str] = None
    num_members: Optional[int] = None

    @classmethod
    def from_slack(cls, channel: dict) -> "Channel":
        return cls(
            id=channel["id"],
            name=channel.get("name", ""),
            is_private=channel.get("is_private", False),
            is_archived=channel.get("is_archived", False),
            is_member=channel.get("is_member", False),
            topic=channel.get("topic", {}).get("value"),
            purpose=channel.get("purpose", {}).get("value"),
            num_members=channel.get("num_members"),
        )


class Message(BaseModel):
    ts: str  # Slack timestamp (unique message ID)
    user: Optional[str] = None
    text: str
    thread_ts: Optional[str] = None
    reply_count: int = 0
    reactions: List[dict] = []
    timestamp: Optional[datetime] = None

    @classmethod
    def from_slack(cls, msg: dict) -> "Message":
        ts = msg.get("ts", "")
        return cls(
            ts=ts,
            user=msg.get("user"),
            text=msg.get("text", ""),
            thread_ts=msg.get("thread_ts"),
            reply_count=msg.get("reply_count", 0),
            reactions=msg.get("reactions", []),
            timestamp=cls._ts_to_datetime(ts),
        )

    @staticmethod
    def _ts_to_datetime(ts: str) -> Optional[datetime]:
        if not ts:
            return None
        try:
            return datetime.fromtimestamp(float(ts))
        except (ValueError, TypeError):
            return None


class MessageList(BaseModel):
    messages: List[Message]
    channel_id: str
    has_more: bool = False


class ChannelList(BaseModel):
    channels: List[Channel]
    total: int


class UserList(BaseModel):
    users: List[User]
    total: int
