from datetime import date, datetime
from typing import Any, List, Optional

from pydantic import Field

from src.apps.base.schemas.common import BaseSchema
from src.apps.files.schemas.file import FileMinimalSchema, FileResponseSchema
from src.apps.user.models.user_model import Users


class UserSchema(BaseSchema):
    """
    Schema for user details.

    Attributes:
        user_id (str): Unique identifier for the user.
        username (str): The username of the user.
        email (str): The email of the user.
        is_active (bool): Whether the user is active.
        is_verified (bool): Whether the user's account is verified.
        is_foreign_visitor (bool): Whether the user is a foreign visitor.
        is_reported (bool): Whether the user is reported.
        is_online (int): Online status of the user (0=offline, 1=online).
        is_deleted (bool): Whether the user is marked as deleted.
        phone (Optional[str]): User's phone number.
        first_name (Optional[str]): User's first name.
        last_name (Optional[str]): User's last name.
        middle_name (Optional[str]): User's middle name.
        gender (Optional[str]): User's gender.
        last_login (datetime): Last login timestamp.
        created_at (datetime): Account creation timestamp.
        updated_at (datetime): Last update timestamp.
        dob (Optional[datetime]): Date of birth.
    """

    id: int = Field(default=None, description="Id of Line Item resource")
    user_id: str = Field(default=None, description="Unique identifier for the user")
    username: str = Field(..., description="Username for login")
    email: str = Field(..., description="User's email address")
    is_active: bool = Field(default=True, description="Account status")
    is_verified: bool = Field(default=False, description="Email verification status")
    phone: Optional[str] = Field(default=None, description="User's phone number")
    first_name: Optional[str] = Field(default=None, description="User's first name")
    last_name: Optional[str] = Field(default=None, description="User's last name")
    gender: Optional[str] = Field(default=None, description="User's gender")
    created_at: Optional[datetime] = Field(default=None, description="Account creation timestamp")
    updated_at: Optional[datetime] = Field(default=None, description="Last update timestamp")


class CurrentUserContext(BaseSchema):
    is_guest: bool
    user: Optional[UserSchema] = None


class UserRolesSchema(BaseSchema):
    label: str = Field(..., description="Name of the role")
    slug: str = Field(..., description="Unique slug identifier for the role")


class UserPermissionSchema(BaseSchema):
    module: str = Field(..., description="Module name for the permission")
    submodule: str = Field(..., description="Submodule name for the permission")
    operation: str = Field(..., description="Operation name for the permission")
    operation_label: str = Field(..., description="Label for the operation")
    is_active: bool = Field(default=True, description="Whether the permission is active")
    display_order: Optional[int] = Field(None, description="Display order for the permission in the UI")


class UserPermissionsSchema(BaseSchema):
    role: UserRolesSchema = Field(None, description="List of roles assigned to the user")
    permissions: Optional[List[UserPermissionSchema]] = Field(
        None, description="List of permissions assigned to the user"
    )


class UserBaseSchema(BaseSchema):
    email: str = Field(..., description="User's email address")
    phone: str = Field(..., description="User's phone number")

    first_name: str = Field(..., description="User's first name")
    last_name: str = Field(..., description="User's last name")
    gender: Optional[str] = Field(None, description="User's gender")   
    
    avatar_id: Optional[int] = Field(None, description="Avatar file ID")


class UserCreateSchema(UserBaseSchema):
    password: str = Field(..., description="User's password")
    confirm_password: str = Field(..., description="Confirmation of the user's password")
    access_level: List[str] = Field(..., description="User's access level in the system")


class UserUpdateSchema(BaseSchema):
    email: Optional[str] = Field(None, description="User's email address")
    phone: Optional[str] = Field(None, description="User's phone number")

    first_name: Optional[str] = Field(None, description="User's first name")
    last_name: Optional[str] = Field(None, description="User's last name")
    gender: Optional[str] = Field(None, description="User's gender")
    
    access_level: Optional[List[str]] = Field(None, description="User's access level in the system")
    avatar_id: Optional[int] = Field(None, description="Avatar file ID")


class UserReturnSchema(BaseSchema):
    """
    Schema for returning user details after operations like registration or update.

    Attributes:
        user (UserSchema): The user details.
    """

    id: int = Field(default=None, description="Id of Line Item resource")
    user_id: str = Field(default=None, description="Unique identifier for the user")
    username: str = Field(..., description="Username for login")

    email: str = Field(..., description="User's email address")
    phone: Optional[str] = Field(default=None, description="User's phone number")

    first_name: Optional[str] = Field(default=None, description="User's first name")
    last_name: Optional[str] = Field(default=None, description="User's last name")
    gender: Optional[str] = Field(default=None, description="User's gender")
    
    is_active: bool = Field(default=True, description="Account status")
    is_verified: bool = Field(default=False, description="Email verification status")
    avatar_id: Optional[int] = Field(None, description="ID of the user's avatar file")

    created_at: Optional[datetime] = Field(None, description="Account creation timestamp")

    avatar: Optional[FileResponseSchema] = Field(None, description="Avatar file details")
    all_roles: Optional[List[str]] = Field(None, description="List of all roles assigned to the user")
    roles: Optional[List[UserPermissionsSchema]] = Field(default=None, description="List of roles assigned to the user")


class UserFilterSchema(BaseSchema):
    """
    Schema for filtering users in queries.

    Attributes:
        username (Optional[str]): Filter by username.
        email (Optional[str]): Filter by email.
        is_active (Optional[bool]): Filter by active status.
        is_verified (Optional[bool]): Filter by verification status.
        is_foreign_visitor (Optional[bool]): Filter by foreign visitor status.
        is_reported (Optional[bool]): Filter by reported status.
        is_online (Optional[int]): Filter by online status.
        is_deleted (Optional[bool]): Filter by deletion status.
    """

    email: Optional[str] = Field(None, description="User's email address")
    phone: Optional[str] = Field(default=None, description="User's phone number")
    first_name: Optional[str] = Field(default=None, description="User's first name")
    last_name: Optional[str] = Field(default=None, description="User's last name")
    is_active: Optional[bool] = Field(default=None, description="Filter by active status")
    is_verified: Optional[bool] = Field(default=None, description="Filter by verification status")
    access_level: Optional[str] = Field(default=None, description="Filter by access level")
    full_name: Optional[str] = Field(None, description="full name")


class ChangePasswordSchema(BaseSchema):
    current_password: str = Field(..., description="Current password of the user")
    new_password: str = Field(..., description="New password for the user")
    confirm_password: str = Field(..., description="Confirmation of the new password")


class UserSessionSchema(BaseSchema):
    session_id: Optional[str]
    ip_addr: Optional[str]
    device: Optional[str]
    os: Optional[str]
    created_at: Optional[datetime]
    user_agent: Optional[str]

    # ✅ Only this — summary string instead of full location block
    location: Optional[str] = None

    
    @classmethod
    def from_orm_with_location(cls, session):
        # Build summary string from non-empty parts
        summary_parts = [session.city, session.region, session.country]
        summary = ", ".join([part for part in summary_parts if part])

        return cls(
            session_id=session.session_id,
            ip_addr=session.ip_addr,
            device=session.device,
            os=session.os,
            created_at=session.created_at,
            user_agent=session.user_agent,
            location=summary or None,
        )


class UserSessionsResponse(BaseSchema):
    max_allowed_sessions: int
    active_count: int
    active_sessions: List[UserSessionSchema]

