"""Administrator access and audit-facing operations."""

from __future__ import annotations

from app.database.models import Admin
from app.database.repositories import Repositories
from app.errors import PermissionDeniedError, ValidationError
from app.utils.validation import parse_telegram_user_id


class AdminService:
    def __init__(self, repos: Repositories) -> None:
        self.repos = repos

    async def seed(self, env_admin_ids: list[int]) -> None:
        await self.repos.admins.sync_env_admins(env_admin_ids)

    async def is_admin(self, telegram_id: int) -> bool:
        return await self.repos.admins.is_admin(telegram_id)

    async def is_primary(self, telegram_id: int) -> bool:
        admin = await self.repos.admins.get(telegram_id)
        return bool(admin and admin.is_active and admin.is_primary)

    async def list_admins(self) -> list[Admin]:
        return await self.repos.admins.list_active()

    async def add(self, actor_id: int, raw_telegram_id: str, title: str | None) -> tuple[Admin, bool]:
        if not await self.is_primary(actor_id):
            raise PermissionDeniedError("فقط مدیر اصلی می‌تواند مدیر اضافه کند.")
        telegram_id = parse_telegram_user_id(raw_telegram_id)
        if telegram_id == actor_id:
            raise ValidationError("شما از قبل مدیر هستید.")
        admin, created = await self.repos.admins.add(telegram_id, title, actor_id)
        await self.repos.audit.log(
            actor_id,
            "admin.add",
            entity_type="admin",
            entity_id=telegram_id,
            details={"created": created},
        )
        return admin, created

    async def remove(self, actor_id: int, telegram_id: int) -> str:
        if not await self.is_primary(actor_id):
            raise PermissionDeniedError("فقط مدیر اصلی می‌تواند مدیر حذف کند.")
        if telegram_id == actor_id:
            raise ValidationError("مدیر اصلی نمی‌تواند خودش را حذف کند.")
        ok, message = await self.repos.admins.remove(telegram_id)
        if ok:
            await self.repos.audit.log(
                actor_id,
                "admin.remove",
                entity_type="admin",
                entity_id=telegram_id,
            )
        return message
