from __future__ import annotations

from typing import Any

from sqlalchemy import select

from app.api.deps import CurrentUserContext
from app.models.financial_record import ExpenseClaim
from app.services.tenant_registry import required_tenant_id


class ExpenseClaimTenantScopeMixin:
    @staticmethod
    def normalize_tenant_id(value: str | None) -> str:
        return required_tenant_id(value)

    @classmethod
    def normalize_context_tenant_id(cls, context_json: dict[str, Any] | None) -> str:
        context = context_json or {}
        return cls.normalize_tenant_id(
            context.get("tenant_id") or context.get("tenantId")
        )

    @classmethod
    def build_claim_tenant_condition(cls, tenant_id: str | None) -> Any:
        """Claim 自身保存结构化租户，任何查询都直接在首个 SQL 过滤。"""

        return ExpenseClaim.tenant_id == cls.normalize_tenant_id(tenant_id)

    @classmethod
    def resolve_claim_tenant_id(cls, db: Any, claim_id: str | None) -> str:
        """从 Claim 结构化字段解析租户；资源缺失时拒绝猜测归属。"""

        normalized_claim_id = str(claim_id or "").strip()
        if not normalized_claim_id:
            raise ValueError("claim_id 不能为空。")
        tenant_id = db.scalar(
            select(ExpenseClaim.tenant_id).where(ExpenseClaim.id == normalized_claim_id)
        )
        if tenant_id is None:
            raise LookupError("报销单不存在。")
        return cls.normalize_tenant_id(tenant_id)

    def apply_tenant_scope(
        self,
        stmt: Any,
        current_user: CurrentUserContext,
    ) -> Any:
        return stmt.where(self.build_claim_tenant_condition(current_user.tenant_id))
