from __future__ import annotations

from app.api.deps import CurrentUserContext

COMMERCIAL_READ_ROLES = {"finance", "executive"}


class CommercialPermissionError(PermissionError):
    pass


class CommercialAccessPolicy:
    """商业数据访问边界；租户身份只从服务端登录上下文取得。"""

    @staticmethod
    def normalized_tenant_id(value: str | None) -> str:
        tenant_id = str(value or "").strip()
        if not tenant_id:
            raise CommercialPermissionError("商业操作缺少可信租户上下文。")
        return tenant_id

    @classmethod
    def tenant_for_current_user(cls, current_user: CurrentUserContext) -> str:
        return cls.normalized_tenant_id(current_user.tenant_id)

    @staticmethod
    def role_codes(current_user: CurrentUserContext) -> set[str]:
        return {
            str(item or "").strip().casefold()
            for item in current_user.role_codes
            if str(item or "").strip()
        }

    @classmethod
    def require_account_read(cls, current_user: CurrentUserContext) -> str:
        tenant_id = cls.tenant_for_current_user(current_user)
        if current_user.is_admin or cls.role_codes(current_user) & COMMERCIAL_READ_ROLES:
            return tenant_id
        raise CommercialPermissionError("只有租户财务、管理层或平台管理员可以查看商业账户。")

    @classmethod
    def require_platform_admin(
        cls,
        current_user: CurrentUserContext,
        *,
        target_tenant_id: str,
    ) -> str:
        if not current_user.is_admin:
            raise CommercialPermissionError("只有平台 admin 管理员可以维护商业配置和内部成本。")
        return cls.normalized_tenant_id(target_tenant_id)

    @classmethod
    def assert_same_tenant(cls, expected_tenant_id: str, actual_tenant_id: str) -> None:
        expected = cls.normalized_tenant_id(expected_tenant_id)
        actual = cls.normalized_tenant_id(actual_tenant_id)
        if expected != actual:
            raise CommercialPermissionError("商业资源不属于目标租户。")


class CommercialConflictError(RuntimeError):
    pass


class CommercialConfigurationError(ValueError):
    pass
