from typing import List, Optional
from fastapi.param_functions import Query
from pydantic import Field, field_validator, ConfigDict
from pydantic.main import BaseModel
from src.apps.base.utils.regexp import USER_UNIQUE_ID, test
from src.apps.role_permissions.schemas.role_permission_common import RoleBase, PermissionBase


class PermissionCreateRequestSchema(PermissionBase):
    model_config = ConfigDict(from_attributes=True)


class PermissionUpdateRequestSchema(PermissionBase):
    model_config = ConfigDict(from_attributes=True)


class RoleCreateRequestSchema(RoleBase):
    model_config = ConfigDict(from_attributes=True)
    
    label: str = Field(
        description="Label for the role, inclusive of alphanumeric characters only"
    )
    permissions: List[int] = Field(
        description="List of permission ids that need to be mapped with this role"
    )
    users: Optional[List[str]] = Field(
        default=None,
        description="Unique IDs of the users. Typically has the form 'usr_xxx'"
    )

    @field_validator("users")
    @classmethod
    def validate_users(cls, v):
        max_limit = 10
        if v:
            if len(v) > max_limit:
                raise ValueError(
                    f"You can provide atmost of {max_limit} user ids at once"
                )
            for item in v:
                if not test(item, USER_UNIQUE_ID):
                    raise ValueError(f"'{item}' is not a valid user id")
        return v


class RoleAssignRequestSchema(BaseModel):
    model_config = ConfigDict(from_attributes=True)
    
    user_id: str = Field(
        description="Unique ID of the user. Typically has the form 'usr_xxx'"
    )
    role_ids: List[int] = Field(
        description="List of role ids that need to be mapped with this user"
    )


class RoleUpdateRequestSchema(RoleBase):
    model_config = ConfigDict(from_attributes=True)
    
    permissions: Optional[List[int]] = Field(
        default=None,
        description="List of permission ids that need to be mapped with this role"
    )
    users: Optional[List[str]] = Field(
        default=None,
        description="Unique IDs of the users. Typically has the form 'usr_xxx'"
    )

    @field_validator("users")
    @classmethod
    def validate_users(cls, v):
        max_limit = 10
        if v:
            if len(v) > max_limit:
                raise ValueError(
                    f"You can provide atmost of {max_limit} user ids at once"
                )
            for item in v:
                if not test(item, USER_UNIQUE_ID):
                    raise ValueError(f"'{item}' is not a valid user id")
        return v


class RoleListFilterSchema(BaseModel):
    search: Optional[str] = Query(default=None, description="Search by role label")


class PermissionListFilterSchema(BaseModel):
    search: Optional[str] = Query(
        default=None, description="Search by permission module or operation"
    )
