"""方案定义 + 功能开关 + API配额"""

from fastapi import Depends, HTTPException
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from app.core.tenant_context import tenant_ctx
from app.db import get_db

# ─── 方案定义 ───

PLANS = {
    "free": {
        "name": "Free",
        "max_storage_mb": 500,
        "max_literature_items": 1000,
        "max_saved_items": 200,
        "max_review_inclusions": 50,  # 系统评价纳入篇数上限
        "api_quota_per_day": 5000,
        "teams": False,
        "approval_workflows": False,
        "sso": False,
        "branding": False,
        "max_team_members": 1,
        "ai_summary": False,
        "ai_translate": False,
        "export_formats": ["bibtex", "ris", "mla"],
        "review_export": True,
        "journal_club": False,
    },
    "pro": {
        "name": "Pro",
        "max_storage_mb": 10_000,
        "max_literature_items": 10_000,
        "max_saved_items": 10_000,
        "max_review_inclusions": 500,
        "api_quota_per_day": 1_000,
        "teams": False,
        "approval_workflows": False,
        "sso": False,
        "branding": False,
        "max_team_members": 1,
        "ai_summary": True,
        "ai_translate": True,
        "export_formats": ["bibtex", "ris", "endnote", "csv", "mla"],
        "review_export": True,
        "journal_club": False,
    },
    "team": {
        "name": "Team",
        "max_storage_mb": -1,
        "max_literature_items": -1,
        "max_saved_items": -1,
        "max_review_inclusions": -1,
        "api_quota_per_day": -1,
        "teams": True,
        "approval_workflows": True,
        "sso": True,
        "branding": False,
        "max_team_members": 100,
        "ai_summary": True,
        "ai_translate": True,
        "export_formats": ["bibtex", "ris", "endnote", "csv", "word", "mla"],
        "review_export": True,
        "journal_club": True,
    },
}


def get_plan(plan_type: str) -> dict:
    return PLANS.get(plan_type, PLANS["free"])


async def get_tenant_plan(db: AsyncSession) -> dict:
    """获取当前租户的方案配置"""
    raw_tid = tenant_ctx.get()
    if not raw_tid:
        return PLANS["free"]
    import uuid

    from app.models.user import Tenant
    tid = uuid.UUID(raw_tid) if isinstance(raw_tid, str) else raw_tid
    result = await db.execute(select(Tenant.plan_type).where(Tenant.id == tid))
    plan_type = result.scalar() or "free"
    return PLANS.get(plan_type, PLANS["free"])


# ─── FastAPI 依赖注入 ───

class RequireFeature:
    """检查当前租户是否有某功能权限"""

    def __init__(self, feature: str):
        self.feature = feature

    async def __call__(self, db: AsyncSession = Depends(get_db)):
        plan = await get_tenant_plan(db)
        if not plan.get(self.feature):
            plan_name = plan["name"]
            raise HTTPException(
                status_code=402,
                detail=f"'{self.feature}' requires {plan_name} plan or higher"
            )
        return True


require_feature = RequireFeature


class CheckQuota:
    """检查租户级别配额（文献保存数/导出次数等）"""

    def __init__(self, resource: str):
        self.resource = resource

    async def __call__(self, db: AsyncSession = Depends(get_db)):
        plan = await get_tenant_plan(db)
        limit = plan.get(self.resource, -1)
        if limit < 0:  # -1 = unlimited
            return True

        raw_tid = tenant_ctx.get()
        if not raw_tid:
            return True
        import uuid

        from sqlalchemy import func
        from sqlalchemy import select as sa_select

        from app.models.interaction import UserLiterature
        from app.models.user import UserTenant

        tid = uuid.UUID(raw_tid) if isinstance(raw_tid, str) else raw_tid

        if self.resource == "max_saved_items":
            # 统计该租户下所有用户的已保存文献数
            result = await db.execute(
                sa_select(func.count(UserLiterature.id))
                .select_from(UserLiterature)
                .join(UserTenant, UserLiterature.user_id == UserTenant.user_id)
                .where(UserTenant.tenant_id == tid)
            )
            count = result.scalar() or 0
            if count >= limit:
                raise HTTPException(
                    status_code=429,
                    detail=f"配额超限: {self.resource} 已达上限 {limit}"
                )

        return True
