from __future__ import annotations

from dataclasses import dataclass

from typing import Optional

try:  # Python 3.9+
    from typing import Annotated  # type: ignore[attr-defined]
except ImportError:  # Python 3.8 fallback
    from typing_extensions import Annotated

import httpx
from fastapi import Depends, Header, HTTPException, status

from app.config import settings


@dataclass
class AuthContext:
    user_id: str
    access_token: str


async def get_current_user(
    authorization: Annotated[Optional[str], Header(convert_underscores=False)] = None,
) -> AuthContext:
    """
    验证 Supabase JWT，stage0 直接依赖 service_role 解析 token。
    生产环境应通过 API Gateway 注入 user。
    """
    if not authorization or not authorization.startswith("Bearer "):
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Missing bearer token")

    token = authorization.replace("Bearer ", "", 1).strip()
    if not token:
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Empty token")

    auth_url = f"{settings.supabase_url.rstrip('/')}/auth/v1/user"
    headers = {
        "Authorization": f"Bearer {token}",
        "apikey": settings.supabase_service_role_key,
    }
    async with httpx.AsyncClient(timeout=10.0) as client:
        try:
            response = await client.get(auth_url, headers=headers)
            response.raise_for_status()
        except httpx.HTTPError as exc:  # pragma: no cover - 网络异常
            raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid Supabase token") from exc

    data = response.json()
    user_id = data.get("id") or data.get("user", {}).get("id")
    if not user_id:
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid Supabase token")

    return AuthContext(user_id=str(user_id), access_token=token)


AuthDep = Annotated[AuthContext, Depends(get_current_user)]
