from typing import Any

from auth.models import PermissionModel, RoleModel, UserModel
from auth.services import AuthService, PermissionService, RoleService, UserService


class AuthLoader:
    def __init__(
        self,
        user_service: UserService,
        role_service: RoleService,
        permission_service: PermissionService,
    ):
        self.user_service = user_service
        self.role_service = role_service
        self.permission_service = permission_service

        self.cache = {"permissions": {}, "roles": {}}

    async def load(self, data: dict[str, Any]):
        await self.load_permissions(data.get("permissions", []))
        await self.load_roles(data.get("roles", []))
        await self.load_users(data.get("users", []))

    async def load_permissions(self, permissions_data: list[str]):
        permissions = []
        for permission_name in permissions_data:
            permission = PermissionModel(name=permission_name)
            self.cache["permissions"][permission_name] = permission
            permissions.append(permission)

        await self.permission_service.create_many(
            permissions,
            auto_commit=True,
        )

    async def load_roles(self, roles_data):
        roles = []
        for role_data in roles_data:
            role = RoleModel(
                name=role_data.get("name"),
                permissions=[
                    self.cache["permissions"][permission_name] for permission_name in role_data.get("permissions")
                ],
            )
            roles.append(role)
            self.cache["roles"][role_data.get("name")] = role
        await self.role_service.create_many(roles, auto_commit=True)

    async def load_users(self, users_data):
        await self.user_service.create_many(
            [
                UserModel(
                    email=user["email"],
                    password=AuthService.hash_password(user["password"]),
                    is_enabled=user['is_enabled'],
                    is_email_verified=user['is_email_verified'],
                    roles=[self.cache["roles"][role_name] for role_name in user["roles"]],
                )
                for user in users_data
            ],
            auto_commit=True,
        )

    async def clear(self):
        await self.permission_service.delete_where(auto_commit=True)
        await self.role_service.delete_where(auto_commit=True)
        await self.user_service.delete_where(auto_commit=True)
