from pydantic import BaseModel, Field, model_validator
from typing import Optional, Union, Any, List
from datetime import datetime
from enum import Enum

class MessageType(str, Enum):
    MESSAGE = "MESSAGE"
    NOTIFICATION = "NOTIFICATION"

class ContentType(str, Enum):
    TEXT = "TEXT"
    IMAGE = "IMAGE"
    VIDEO = "VIDEO"
    FILE = "FILE"
    # 用户在应用内发起的“申请通知”，用于在私信界面展示通知样式（携带 action_url/action_text）
    USER_NOTIFICATION = "USER_NOTIFICATION"

class MessageBase(BaseModel):
    title: str = Field(..., max_length=255)
    content: Union[str, dict, Any] = Field(..., description="内容")
    content_type: ContentType = ContentType.TEXT
    
    type: MessageType = MessageType.MESSAGE
    app_id: Optional[str] = None  # 改为字符串类型，支持开发者保存的字符串 app_id
    
    action_url: Optional[str] = None
    action_text: Optional[str] = None
    
    # SSO 扩展
    target_url: Optional[str] = None
    auto_sso: bool = False

class MessageCreate(MessageBase):
    receiver_id: Optional[int] = None
    app_user_id: Optional[str] = None
    sender_app_user_id: Optional[str] = None  # 应用发信时可选：帐内发起人，解析后写入 sender_id，用于审计和会话聚合
    is_broadcast: bool = False
    
    @model_validator(mode='after')
    def check_receiver(self):
        if self.is_broadcast:
            return self
        if not self.receiver_id and not (self.app_user_id and self.app_id):
            raise ValueError("非广播消息必须提供 receiver_id，或者同时提供 app_user_id 和 app_id")
        return self

class MessageUpdate(BaseModel):
    is_read: Optional[bool] = None

class MessageResponse(BaseModel):
    id: int
    sender_id: Optional[int]
    receiver_id: int
    app_id: Optional[int]
    app_name: Optional[str] = None  # 应用名称，用于前端显示
    
    type: MessageType
    content_type: ContentType
    
    title: str
    content: str  # DB 中存的是字符串
    
    action_url: Optional[str]
    action_text: Optional[str]
    
    is_read: bool
    created_at: datetime
    read_at: Optional[datetime]

    class Config:
        from_attributes = True

class ConversationResponse(BaseModel):
    user_id: int
    username: str
    full_name: Optional[str]
    unread_count: int
    last_message: str
    last_message_type: ContentType
    updated_at: datetime

    # 系统会话标记及应用信息（用于拆分不同平台的系统通知会话）
    is_system: bool = False
    app_id: Optional[int] = None
    app_name: Optional[str] = None
    # 业务侧 Application.app_id 字符串（与 SSO / 客户端缓存键一致）；仅按应用拆分的系统会话可能有值
    application_app_id: Optional[str] = None
    icon_url: Optional[str] = None
    icon_object_key: Optional[str] = None

    # 列表副文案：有 app 的应用通知为「应用通知」；无 app 的旧系统会话为空；用户会话为对端组织名，无组织为空
    remarks: Optional[str] = None

    class Config:
        from_attributes = True

class AdminMessageItem(BaseModel):
    """运维消息查询返回的单条消息（含发送者/接收者/应用基础信息）。"""
    id: int
    type: MessageType
    content_type: ContentType
    title: str
    content: str
    action_url: Optional[str] = None
    action_text: Optional[str] = None
    is_read: bool
    created_at: datetime
    read_at: Optional[datetime] = None

    sender_id: Optional[int] = None
    sender_mobile: Optional[str] = None
    sender_name: Optional[str] = None

    receiver_id: int
    receiver_mobile: Optional[str] = None
    receiver_name: Optional[str] = None

    app_id: Optional[int] = None
    app_app_id: Optional[str] = None
    app_name: Optional[str] = None

    class Config:
        from_attributes = True


class AdminMessageList(BaseModel):
    total: int
    items: List[AdminMessageItem]


# Device Schema
class DeviceRegister(BaseModel):
    device_token: str
    platform: str
    device_name: Optional[str] = None
