"""
User Model - Admin and Client Users
"""
from datetime import datetime
from sqlalchemy import Column, Integer, String, Boolean, DateTime, ForeignKey, Enum as SQLEnum
from sqlalchemy.orm import relationship
import enum

from app.models.base import Base, TimestampMixin, SoftDeleteMixin


class UserRole(enum.Enum):
    SUPER_ADMIN = "super_admin"      # Platform admin (us)
    ADMIN = "admin"                   # Platform staff
    CLIENT_OWNER = "client_owner"     # Client account owner
    CLIENT_ADMIN = "client_admin"     # Client admin
    CLIENT_USER = "client_user"       # Client team member


class User(Base, TimestampMixin, SoftDeleteMixin):
    """
    User Model - For both platform admins and client users
    """
    __tablename__ = "users"

    id = Column(Integer, primary_key=True, index=True)
    client_id = Column(Integer, ForeignKey("clients.id"), nullable=True, index=True)  # Null for platform admins

    # Basic Info
    email = Column(String(255), unique=True, nullable=False, index=True)
    password_hash = Column(String(255), nullable=False)
    first_name = Column(String(100), nullable=False)
    last_name = Column(String(100), nullable=True)
    phone = Column(String(20), nullable=True)
    avatar_url = Column(String(500), nullable=True)

    # Role & Permissions
    role = Column(SQLEnum(UserRole), default=UserRole.CLIENT_USER, nullable=False)
    is_active = Column(Boolean, default=True)
    is_verified = Column(Boolean, default=False)

    # Authentication
    last_login_at = Column(DateTime, nullable=True)
    last_login_ip = Column(String(45), nullable=True)
    failed_login_attempts = Column(Integer, default=0)
    locked_until = Column(DateTime, nullable=True)

    # Email Verification
    email_verified_at = Column(DateTime, nullable=True)
    email_verification_token = Column(String(100), nullable=True)

    # Password Reset
    password_reset_token = Column(String(100), nullable=True)
    password_reset_expires = Column(DateTime, nullable=True)

    # 2FA
    two_factor_enabled = Column(Boolean, default=False)
    two_factor_secret = Column(String(100), nullable=True)

    # OAuth
    oauth_provider = Column(String(50), nullable=True)  # google, microsoft, etc.
    oauth_id = Column(String(255), nullable=True)  # Provider's user ID
    oauth_access_token = Column(String(500), nullable=True)
    oauth_refresh_token = Column(String(500), nullable=True)
    oauth_token_expires_at = Column(DateTime, nullable=True)

    # Preferences
    timezone = Column(String(50), default="Asia/Kolkata")
    language = Column(String(10), default="en")
    notification_email = Column(Boolean, default=True)
    notification_sms = Column(Boolean, default=False)

    # Relationships
    client = relationship("Client", back_populates="users")

    @property
    def full_name(self):
        return f"{self.first_name} {self.last_name or ''}".strip()

    @property
    def is_platform_admin(self):
        return self.role in [UserRole.SUPER_ADMIN, UserRole.ADMIN]

    @property
    def is_client_admin(self):
        return self.role in [UserRole.CLIENT_OWNER, UserRole.CLIENT_ADMIN]

    def __repr__(self):
        return f"<User(id={self.id}, email='{self.email}')>"


class UserSession(Base, TimestampMixin):
    """
    User Session Model - Track active sessions
    """
    __tablename__ = "user_sessions"

    id = Column(Integer, primary_key=True, index=True)
    user_id = Column(Integer, ForeignKey("users.id"), nullable=False, index=True)

    # Session Details
    session_token = Column(String(255), unique=True, nullable=False, index=True)
    refresh_token = Column(String(255), unique=True, nullable=True)

    # Device Info
    device_type = Column(String(50), nullable=True)  # web, mobile, api
    device_name = Column(String(100), nullable=True)
    browser = Column(String(100), nullable=True)
    os = Column(String(100), nullable=True)
    ip_address = Column(String(45), nullable=True)

    # Expiry
    expires_at = Column(DateTime, nullable=False)
    refresh_expires_at = Column(DateTime, nullable=True)

    # Status
    is_active = Column(Boolean, default=True)
    revoked_at = Column(DateTime, nullable=True)

    def __repr__(self):
        return f"<UserSession(id={self.id}, user_id={self.user_id})>"


class AuditLog(Base, TimestampMixin):
    """
    Audit Log - Track important user actions
    """
    __tablename__ = "audit_logs"

    id = Column(Integer, primary_key=True, index=True)
    user_id = Column(Integer, ForeignKey("users.id"), nullable=True)
    client_id = Column(Integer, ForeignKey("clients.id"), nullable=True)

    # Action Details
    action = Column(String(100), nullable=False)  # e.g., "user.login", "client.update"
    resource_type = Column(String(50), nullable=True)  # e.g., "client", "user", "subscription"
    resource_id = Column(Integer, nullable=True)

    # Data
    old_values = Column(String, nullable=True)  # JSON string of old values
    new_values = Column(String, nullable=True)  # JSON string of new values

    # Context
    ip_address = Column(String(45), nullable=True)
    user_agent = Column(String(500), nullable=True)

    def __repr__(self):
        return f"<AuditLog(id={self.id}, action='{self.action}')>"
