import re
from typing import List, Optional

from fastapi.param_functions import Query
from pydantic import validator
from pydantic.fields import Field
from pydantic.main import BaseModel

from src.apps.role_permission.schemas.common import PermissionBase, RoleBase

# Define a regex pattern for user ID validation
USER_UNIQUE_ID = r"^[a-zA-Z0-9_-]+$"


def test(value, pattern):
    return re.match(pattern, value) is not None


class PermissionCreateRequestSchema(PermissionBase):
    pass


class PermissionUpdateRequestSchema(PermissionBase):
    pass


class RoleCreateRequestSchema(RoleBase):
    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(None, description="Unique IDs of the users.")

    @validator("users")
    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):
    user_id: str = Field(description="Unique ID of the user.")
    role_ids: List[int] = Field(description="List of role ids that need to be mapped with this user")


class RoleUpdateRequestSchema(RoleBase):
    permissions: Optional[List[int]] = Field(
        None, description="List of permission ids that need to be mapped with this role"
    )
    users: Optional[List[str]] = Field(None, description="Unique IDs of the users.")

    @validator("users")
    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] = None
    show_all_roles: Optional[bool] = Query(
        True,
        description="If true, it will show all roles including the ones that are not assigned to any user.",
    )


class PermissionListFilterSchema(BaseModel):
    search: Optional[str] = None
