"""سرویس مدیریت عضویت کاربر در tenant (TenantMembership)."""
from __future__ import annotations

from typing import Sequence
from uuid import UUID

from sqlalchemy.ext.asyncio import AsyncSession

from app.models.enums import MembershipStatus, TenantMembershipRole
from app.models.membership import TenantMembership
from app.repositories.membership import TenantMembershipRepository
from shared.auth import PlatformRole, has_role
from shared.exceptions import ForbiddenError
from shared.security import CurrentUser

# نقش‌هایی که اجازه مدیریت تنظیمات tenant (برندینگ/دامنه/تکمیل onboarding) را دارند.
TENANT_MANAGER_ROLES = {TenantMembershipRole.TENANT_OWNER, TenantMembershipRole.TENANT_ADMIN}


class MembershipService:
    def __init__(self, session: AsyncSession) -> None:
        self.session = session
        self.repo = TenantMembershipRepository(session)

    async def create_owner_membership(
        self, tenant_id: UUID, user_id: UUID
    ) -> TenantMembership:
        existing = await self.repo.get_by_tenant_and_user(tenant_id, user_id)
        if existing is not None:
            existing.role = TenantMembershipRole.TENANT_OWNER
            existing.is_owner = True
            existing.status = MembershipStatus.ACTIVE
            await self.session.commit()
            await self.session.refresh(existing)
            return existing

        membership = TenantMembership(
            tenant_id=tenant_id,
            user_id=user_id,
            role=TenantMembershipRole.TENANT_OWNER,
            is_owner=True,
            status=MembershipStatus.ACTIVE,
        )
        await self.repo.add(membership)
        await self.session.commit()
        await self.session.refresh(membership)
        return membership

    async def get(self, tenant_id: UUID, user_id: UUID) -> TenantMembership | None:
        return await self.repo.get_by_tenant_and_user(tenant_id, user_id)

    async def list_for_user(self, user_id: UUID) -> Sequence[TenantMembership]:
        return await self.repo.list_by_user(user_id)

    async def list_for_tenant(self, tenant_id: UUID) -> Sequence[TenantMembership]:
        return await self.repo.list_by_tenant(tenant_id)

    async def ensure_role(
        self,
        *,
        tenant_id: UUID,
        core_user_id: UUID,
        current_user: CurrentUser,
        allowed_roles: set[TenantMembershipRole] = frozenset(TENANT_MANAGER_ROLES),
    ) -> TenantMembership | None:
        """اطمینان از این‌که کاربر جاری نقش کافی روی این tenant دارد.

        platform_admin همیشه دسترسی کامل دارد (bypass).
        """
        if has_role(current_user, PlatformRole.PLATFORM_ADMIN):
            return None

        membership = await self.get(tenant_id, core_user_id)
        if (
            membership is None
            or membership.status != MembershipStatus.ACTIVE
            or membership.role not in allowed_roles
        ):
            raise ForbiddenError("دسترسی کافی برای مدیریت این tenant ندارید")
        return membership

    async def count_active_owners(self, tenant_id: UUID) -> int:
        return await self.repo.count_active_owners(tenant_id)
