a
    gh$                     @   sx   d dl m Z  d dlmZmZmZmZmZmZmZm	Z	 d dl
mZ d dlmZ d dlmZ d dlmZ G dd deZd	S )
    )datetime)StringField
EmailFieldDateTimeFieldBooleanField	ListFieldReferenceFieldCASCADEEmbeddedDocumentField)bcrypt)TimestampedMixin)Role)Profilec                       s|  e Zd ZdZedddZeddddZeddd	Zed
ddZ	edd
g dddZ
edddZedddZedddZedddZedddZedddZedddZedddZedddZeejdddZedddZeeddZeeed d!Z d"d# Z!e"d$d%d&Z#e"d$d'd(Z$d)d* Z%d+d, Z&d-d. Z'd/d0 Z(d1d2 Z)d3d4 Z*d5d6 Z+d7d8 Z,d9d: Z-d;d< Z. fd=d>Z/  Z0S )?Usera  
    Professional User model for managing user information.

    Attributes:
        username (str): The unique username of the user (required).
        email (str): The email address of the user (required, unique).
        password (str): The user's password (required).
        first_name (str): The user's first name.
        last_name (str): The user's last name. 
        is_verified (bool): A flag indicating if the user's email is verified.
        is_superuser (bool): A flag indicating if the user is a superuser.
        is_admin (bool): A flag indicating if the user is an admin.
        is_active (bool): A flag indicating if the user account is active.
        is_staff (bool): A flag indicating if the user is staff.
        last_login (datetime): The date and time of the user's last login.
        date_joined (datetime): The date and time of user registration (auto-generated).
        roles (list of Role): User roles or permissions (related to Role model).
        last_seen_at (datetime): The date and time when the user was last seen.
        notif_enabled (bool): A flag indicating if notifications are enabled for the user.
        is_online (bool): A flag indicating if the user is currently online.
        is_blocked (bool): A flag indicating if the user is blocked.

    Methods:
        __str__(): Return the username as a string representation of the user.
        set_password(password: str): Set the user's password (typically after hashing).
        check_password(password: str): Check if the provided password matches the user's password.
        add_role(role: Role): Add a role to the user's list of roles.
        remove_role(role: Role): Remove a role from the user's list of roles.
        mark_as_online(): Mark the user as online.
        mark_as_offline(): Mark the user as offline.
        block_user(): Block the user, preventing certain actions.
        unblock_user(): Unblock the user, allowing them to resume normal activities.
        update_last_seen(): Update the user's last seen timestamp to the current time.

    2   z The unique username of the user.)
max_length	help_textTzThe email address of the user.)requireduniquer   zThe user's password.)r   r      zThe user's Company name.)zAnonymous CompanyzBrands CompanyzAd Agency CompanyzTV Channels CompanyzThe user's Company type.)r   r   choicesr   Fz2A flag indicating if the user's email is verified.)defaultr   z-A flag indicating if the user is a superuser.z*A flag indicating if the user is an admin.z0A flag indicating if the user account is active.z'A flag indicating if the user is staff.z2A flag indicating if the user is currently online.z)A flag indicating if the user is blocked.z<A flag indicating if notifications are enabled for the user.Nz+The date and time of the user's last login.z&The date and time of user registration)r   readonlyr   z.The date and time when the user was last seen.zUser profile information.)r   z2User roles or permissions (related to Role model).)reverse_delete_ruler   c                 C   s   | j S )z
        Return the username as a string representation of the user.

        Returns:
            str: The username of the user.
        )usernameself r   /app/app/models/user.py__str__   s    zUser.__str__)passwordc                 C   s   t |d| _dS )z
        Set the user's password, typically after hashing it.

        Args:
            password (str): The user's password.

        Returns:
            None
        zutf-8N)r   generate_password_hashdecoder    r   r    r   r   r   set_password   s    
zUser.set_passwordc                 C   s   t | j|S )z
        Check if the provided password matches the user's password.

        Args:
            password (str): The password to check.

        Returns:
            bool: True if the password matches, False otherwise.
        )r   check_password_hashr    r#   r   r   r   check_password   s    
zUser.check_passwordc                 C   s4   || j vr0t|d}|  | j | |   dS )z
        Add a role to the user's list of roles.

        Args:
            role (Role): The role to add.

        Returns:
            None
        nameN)rolesr   saveappend)r   roleZnew_roler   r   r   add_role   s
    

zUser.add_rolec                 C   s   || j v r| j | dS )z
        Remove a role from the user's list of roles.

        Args:
            role (Role): The role to remove.

        Returns:
            None
        N)r)   remove)r   r,   r   r   r   remove_role   s    
zUser.remove_rolec                 C   s>   | j s:tjdd }|s,tdd}|  || _ |   d S )Nadminr'   )r,   r   objectsfirstr*   )r   Zclient_roler   r   r   ensure_client_role   s    
zUser.ensure_client_rolec                 C   s   | j  | _ |   dS )z
        Toggle the active status of the user.

        If the user is currently active, this function will deactivate the user.
        If the user is currently inactive, this function will activate the user.
        N)	is_activer*   r   r   r   r   toggle_active_status   s    
zUser.toggle_active_statusc                 C   s
   d| _ dS )zM
        Mark the user as online.

        Returns:
            None
        TN	is_onliner   r   r   r   mark_as_online   s    zUser.mark_as_onlinec                 C   s
   d| _ dS )zN
        Mark the user as offline.

        Returns:
            None
        FNr6   r   r   r   r   mark_as_offline   s    zUser.mark_as_offlinec                 C   s
   d| _ dS )zj
        Block the user, preventing them from certain actions.

        Returns:
            None
        TN
is_blockedr   r   r   r   
block_user   s    zUser.block_userc                 C   s
   d| _ dS )zq
        Unblock the user, allowing them to resume normal activities.

        Returns:
            None
        FNr:   r   r   r   r   unblock_user   s    zUser.unblock_userc                 C   s   t  | _dS )zo
        Update the user's last seen timestamp to the current time.

        Returns:
            None
        N)r   utcnowlast_seen_atr   r   r   r   update_last_seen   s    zUser.update_last_seenc                 C   s   t  | _dS )zp
        Update the user's last login timestamp to the current time.

        Returns:
            None
        N)r   r>   
last_loginr   r   r   r   update_last_login  s    zUser.update_last_loginc                    s   t t|  }|dd |dd |dd |ddsV|dd |dd | |d|d< | |d	|d	< | |d
|d
< |dd | j |d< |S )z7
        Convert the document to a dictionary.
        idNr    r7   deletedFZ
deleted_atdate_joinedrA   r?   _clsr,   )superr   to_dictpopgetZ_format_datetimer,   )r   Z	user_dict	__class__r   r   rH     s    zUser.to_dict)1__name__
__module____qualname____doc__r   r   r   emailr    Zcompany_nameZcompany_typer   Zis_verifiedis_superuseris_adminr4   is_staffr7   r;   Znotif_enabledr   rA   r   r>   rE   r?   r
   r   profiler   r   r	   r,   r   strr$   r&   r-   r/   r3   r5   r8   r9   r<   r=   r@   rB   rH   __classcell__r   r   rK   r   r      s   $	
						r   N)r   mongoenginer   r   r   r   r   r   r	   r
   app.config.extensionsr   app.models.baser   app.models.roler   app.models.profiler   r   r   r   r   r   <module>   s   (