"""
Internal Team Chat Models for enterprise communication between staff, admin, and housekeeping.
"""
from sqlalchemy import Column, Integer, String, Text, ForeignKey, DateTime, Enum, Boolean, Table
from sqlalchemy.orm import relationship
from datetime import datetime
import enum
from ...shared.config.database import Base


class ChannelType(str, enum.Enum):
    """Types of chat channels"""
    direct = 'direct'  # 1-on-1 direct message
    group = 'group'    # Custom group chat
    department = 'department'  # Department-wide channel (housekeeping, front-desk, etc.)
    announcement = 'announcement'  # Admin announcements (read-only for non-admins)


class MessagePriority(str, enum.Enum):
    """Message priority levels"""
    normal = 'normal'
    high = 'high'
    urgent = 'urgent'


# Many-to-many relationship table for channel members
team_channel_members = Table(
    'team_channel_members',
    Base.metadata,
    Column('channel_id', Integer, ForeignKey('team_channels.id'), primary_key=True),
    Column('user_id', Integer, ForeignKey('users.id'), primary_key=True),
    Column('joined_at', DateTime, default=datetime.utcnow, nullable=False),
    Column('is_muted', Boolean, default=False, nullable=False),
    Column('last_read_at', DateTime, nullable=True)
)


class TeamChannel(Base):
    """
    Team communication channels for internal messaging.
    Supports direct messages, group chats, department channels, and announcements.
    """
    __tablename__ = 'team_channels'
    
    id = Column(Integer, primary_key=True, index=True, autoincrement=True)
    name = Column(String(100), nullable=True)  # Optional for direct messages
    description = Column(Text, nullable=True)
    channel_type = Column(Enum(ChannelType), nullable=False, default=ChannelType.group)
    
    # For department channels
    department = Column(String(50), nullable=True)  # 'housekeeping', 'front-desk', 'management', etc.
    
    # Creator/owner
    created_by = Column(Integer, ForeignKey('users.id'), nullable=False)
    
    # Channel settings
    is_active = Column(Boolean, default=True, nullable=False)
    is_private = Column(Boolean, default=False, nullable=False)  # Private channels require invitation
    
    # Timestamps
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
    last_message_at = Column(DateTime, nullable=True)
    
    # Relationships
    creator = relationship('User', foreign_keys=[created_by])
    members = relationship('User', secondary=team_channel_members, backref='team_channels')
    messages = relationship('TeamMessage', back_populates='channel', cascade='all, delete-orphan', 
                          order_by='TeamMessage.created_at')
    
    def __repr__(self):
        return f"<TeamChannel(id={self.id}, name='{self.name}', type='{self.channel_type}')>"


class TeamMessage(Base):
    """
    Messages within team channels.
    """
    __tablename__ = 'team_messages'
    
    id = Column(Integer, primary_key=True, index=True, autoincrement=True)
    channel_id = Column(Integer, ForeignKey('team_channels.id'), nullable=False, index=True)
    sender_id = Column(Integer, ForeignKey('users.id'), nullable=False, index=True)
    
    # Message content
    content = Column(Text, nullable=False)
    priority = Column(Enum(MessagePriority), default=MessagePriority.normal, nullable=False)
    
    # For replies/threads
    reply_to_id = Column(Integer, ForeignKey('team_messages.id'), nullable=True)
    
    # Message metadata
    is_edited = Column(Boolean, default=False, nullable=False)
    edited_at = Column(DateTime, nullable=True)
    is_deleted = Column(Boolean, default=False, nullable=False)
    deleted_at = Column(DateTime, nullable=True)
    
    # For task/booking references
    reference_type = Column(String(50), nullable=True)  # 'booking', 'task', 'room', etc.
    reference_id = Column(Integer, nullable=True)
    
    # Timestamps
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    
    # Relationships
    channel = relationship('TeamChannel', back_populates='messages')
    sender = relationship('User', foreign_keys=[sender_id])
    reply_to = relationship('TeamMessage', remote_side=[id], backref='replies')
    read_receipts = relationship('TeamMessageReadReceipt', back_populates='message', cascade='all, delete-orphan')
    
    def __repr__(self):
        return f"<TeamMessage(id={self.id}, channel_id={self.channel_id}, sender_id={self.sender_id})>"


class TeamMessageReadReceipt(Base):
    """
    Track which users have read which messages.
    """
    __tablename__ = 'team_message_read_receipts'
    
    id = Column(Integer, primary_key=True, index=True, autoincrement=True)
    message_id = Column(Integer, ForeignKey('team_messages.id'), nullable=False, index=True)
    user_id = Column(Integer, ForeignKey('users.id'), nullable=False, index=True)
    read_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    
    # Relationships
    message = relationship('TeamMessage', back_populates='read_receipts')
    user = relationship('User')
    
    def __repr__(self):
        return f"<TeamMessageReadReceipt(message_id={self.message_id}, user_id={self.user_id})>"


class UserPresence(Base):
    """
    Track user online/offline status for real-time features.
    """
    __tablename__ = 'user_presence'
    
    id = Column(Integer, primary_key=True, index=True, autoincrement=True)
    user_id = Column(Integer, ForeignKey('users.id'), unique=True, nullable=False, index=True)
    
    # Status
    status = Column(String(20), default='offline', nullable=False)  # online, away, busy, offline
    custom_status = Column(String(100), nullable=True)  # Custom status message
    
    # Activity tracking
    last_seen_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    last_active_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    
    # Device info
    device_type = Column(String(50), nullable=True)  # web, mobile, desktop
    
    # Relationships
    user = relationship('User', backref='presence')
    
    def __repr__(self):
        return f"<UserPresence(user_id={self.user_id}, status='{self.status}')>"

