from abc import ABC, abstractmethod

from app.domain.entities.users_roles import CompanyUser, Role, UsersRolesSummary


class UsersRolesRepository(ABC):
    @abstractmethod
    async def create_role(self, role: Role) -> Role:
        pass

    @abstractmethod
    async def get_role(self, role_id: str, company_id: str) -> Role | None:
        pass

    @abstractmethod
    async def get_role_by_slug(self, company_id: str, slug: str) -> Role | None:
        pass

    @abstractmethod
    async def get_role_by_name(self, company_id: str, name: str) -> Role | None:
        pass

    @abstractmethod
    async def list_roles(
        self, company_id: str, *, search: str | None = None, skip: int = 0, limit: int = 100
    ) -> list[Role]:
        pass

    @abstractmethod
    async def count_roles(self, company_id: str, *, search: str | None = None) -> int:
        pass

    @abstractmethod
    async def update_role(self, role_id: str, role: Role) -> Role | None:
        pass

    @abstractmethod
    async def delete_role(self, role_id: str, company_id: str) -> bool:
        pass

    @abstractmethod
    async def count_users_for_role(self, role_id: str, company_id: str) -> int:
        pass

    @abstractmethod
    async def get_summary(self, company_id: str) -> UsersRolesSummary:
        pass

    @abstractmethod
    async def create_user(self, user: CompanyUser) -> CompanyUser:
        pass

    @abstractmethod
    async def get_user(self, user_id: str, company_id: str) -> CompanyUser | None:
        pass

    @abstractmethod
    async def get_user_global(self, user_id: str) -> CompanyUser | None:
        pass

    @abstractmethod
    async def find_by_login(self, identifier: str) -> CompanyUser | None:
        pass

    @abstractmethod
    async def update_last_login(self, user_id: str) -> None:
        pass

    @abstractmethod
    async def get_user_by_username(
        self, company_id: str, username: str
    ) -> CompanyUser | None:
        pass

    @abstractmethod
    async def get_user_by_email(self, company_id: str, email: str) -> CompanyUser | None:
        pass

    @abstractmethod
    async def get_user_by_employee_code(
        self, company_id: str, employee_code: str
    ) -> CompanyUser | None:
        pass

    @abstractmethod
    async def list_users(
        self,
        company_id: str,
        *,
        role_id: str | None = None,
        department_id: str | None = None,
        status: str | None = None,
        search: str | None = None,
        sort_by: str = "full_name",
        sort_dir: str = "asc",
        skip: int = 0,
        limit: int = 100,
    ) -> list[CompanyUser]:
        pass

    @abstractmethod
    async def count_users(
        self,
        company_id: str,
        *,
        role_id: str | None = None,
        department_id: str | None = None,
        status: str | None = None,
        search: str | None = None,
    ) -> int:
        pass

    @abstractmethod
    async def update_user(self, user_id: str, user: CompanyUser) -> CompanyUser | None:
        pass

    @abstractmethod
    async def delete_user(self, user_id: str, company_id: str) -> bool:
        pass
