"""多租户公共依赖 — 账套模式：token优先，query/header降级为Bot服务白名单"""
from fastapi import Request, Header, Query, Depends, HTTPException
from typing import Optional
from sqlalchemy.orm import Session

from app.database import get_db
from app.auth_middleware import get_token_entity_id
from app.models import Entity


def get_entity_id(
    request: Request,
    x_entity_id: Optional[str] = Header(None, alias="X-Entity-Id"),
    entity_id: Optional[int] = Query(None, ge=1),
    db: Session = Depends(get_db),
) -> int:
    """解析当前企业ID（账套模式）：token优先 → query/header（Bot白名单）→ 默认1

    解析链（倒置后）：
      1. Authorization Bearer token → 优先返回 token.entity_id（唯一可信来源）
      2. query参数 / X-Entity-Id header → 仅Bot服务通道使用（校验entity状态active）
      3. body中的 entity_id（POST场景）→ Bot服务通道兼容
      4. 兜底默认 1（酣客）

    安全说明：登录用户必须通过token绑定账套，query/header传入的entity_id
    在token存在时被忽略，防止越权传参（旧漏洞：query优先且无授权校验）。
    """
    # 1. token优先（账套模式唯一来源）
    auth = request.headers.get("Authorization", "")
    if auth.startswith("Bearer "):
        token_entity = get_token_entity_id(auth[7:])
        if token_entity is not None:
            # 越权防护：显式传入的 query/header entity_id 与 token 绑定不一致 → 403
            explicit = None
            if entity_id is not None:
                explicit = entity_id
            elif x_entity_id and x_entity_id.isdigit():
                explicit = int(x_entity_id)
            if explicit is not None and explicit != token_entity:
                raise HTTPException(403, f"无权访问企业 entity_id={explicit}（当前账套: {token_entity}）")
            return token_entity
        # token存在但是旧格式/无entity → 账套模式下强制走白名单或默认（由require_auth拦截）
        # 这里不抛401：公开接口可能带旧token，交给require_auth统一处理

    # 2. query/header → Bot服务通道白名单（校验entity状态active）
    candidate = None
    if entity_id is not None:
        candidate = entity_id
    elif x_entity_id and x_entity_id.isdigit():
        candidate = int(x_entity_id)

    # 3. body 中的 entity_id（POST场景，Bot通道兼容）
    if candidate is None and request.method in ("POST", "PUT", "PATCH"):
        try:
            body = request.state.body_json or {}
            if body.get("entity_id"):
                candidate = int(body["entity_id"])
        except Exception:
            pass

    if candidate is not None:
        ent = db.query(Entity).filter(Entity.id == candidate).first()
        if ent and ent.status == "active":
            return candidate
        # Bot通道校验不通过：不返回默认，直接拒绝（防越权注入无效entity）
        raise HTTPException(403, f"企业 entity_id={candidate} 不存在或未激活")

    return 1  # 默认酣客（无token、无参数时兜底，兼容存量公开接口）


def resolve_entity_for_request(request: Request, fallback: int = 1) -> int:
    """账套模式：请求级entity解析（供从body读取entity_id的接口使用）
    登录用户（带Bearer token）→ token绑定的entity（唯一来源）
    无token（Bot服务通道）→ 回退到调用方传入的fallback（body中的entity_id等）
    """
    auth = request.headers.get("Authorization", "")
    if auth.startswith("Bearer "):
        token_entity = get_token_entity_id(auth[7:])
        if token_entity is not None:
            return token_entity
    return fallback
