"""UAA Client for Python/FastAPI"""

import httpx
from typing import Optional
from .models import User, AuthResponse, VerifyResponse


class UAAClient:
    """UAA Client for authentication operations"""

    def __init__(
        self,
        project_id: str,
        base_url: str = "https://auth.opensora.store/api/v1"
    ):
        """
        Initialize UAA client

        Args:
            project_id: Your project ID from UAA
            base_url: UAA API base URL
        """
        self.project_id = project_id
        self.base_url = base_url
        self.client = httpx.AsyncClient(timeout=30.0)

    async def login_with_google(self, credential: str) -> AuthResponse:
        """
        Login with Google OAuth credential (ID Token from One Tap or Google Sign-In)

        Args:
            credential: Google ID Token (JWT)

        Returns:
            AuthResponse with tokens and user info

        Raises:
            httpx.HTTPError: If the request fails
        """
        response = await self.client.post(
            f"{self.base_url}/auth/google/id-token",
            json={
                "credential": credential,
                "client_id": self.project_id,
            }
        )
        response.raise_for_status()
        return AuthResponse(**response.json())

    async def login_with_apple(
        self,
        code: str,
        id_token: str
    ) -> AuthResponse:
        """
        Login with Apple OAuth

        Args:
            code: Authorization code from Apple
            id_token: ID token from Apple

        Returns:
            AuthResponse with tokens and user info

        Raises:
            httpx.HTTPError: If the request fails
        """
        response = await self.client.post(
            f"{self.base_url}/auth/apple/callback",
            json={
                "code": code,
                "id_token": id_token,
                "project_id": self.project_id,
            }
        )
        response.raise_for_status()
        return AuthResponse(**response.json())

    async def verify_token(self, token: str) -> VerifyResponse:
        """
        Verify access token

        Args:
            token: Access token to verify

        Returns:
            VerifyResponse with validation result and user info
        """
        try:
            response = await self.client.get(
                f"{self.base_url}/auth/verify",
                headers={"Authorization": f"Bearer {token}"}
            )
            response.raise_for_status()
            data = response.json()
            return VerifyResponse(valid=True, user=User(**data["user"]))
        except httpx.HTTPError:
            return VerifyResponse(valid=False)

    async def get_current_user(self, token: str) -> User:
        """
        Get current user information

        Args:
            token: Access token

        Returns:
            User object

        Raises:
            httpx.HTTPError: If the request fails
        """
        response = await self.client.get(
            f"{self.base_url}/user/me",
            headers={"Authorization": f"Bearer {token}"}
        )
        response.raise_for_status()
        return User(**response.json())

    async def refresh_token(self, refresh_token: str) -> AuthResponse:
        """
        Refresh access token

        Args:
            refresh_token: Refresh token

        Returns:
            AuthResponse with new tokens

        Raises:
            httpx.HTTPError: If the request fails
        """
        response = await self.client.post(
            f"{self.base_url}/auth/refresh",
            json={"refresh_token": refresh_token}
        )
        response.raise_for_status()
        return AuthResponse(**response.json())

    async def logout(self, token: str) -> None:
        """
        Logout and revoke tokens

        Args:
            token: Access token

        Raises:
            httpx.HTTPError: If the request fails
        """
        response = await self.client.post(
            f"{self.base_url}/auth/logout",
            headers={"Authorization": f"Bearer {token}"}
        )
        response.raise_for_status()

    async def close(self):
        """Close the HTTP client"""
        await self.client.aclose()

    async def __aenter__(self):
        return self

    async def __aexit__(self, exc_type, exc_val, exc_tb):
        await self.close()


class UAAAuth:
    """
    FastAPI dependency for authentication

    Usage:
        from opensora_uaa import UAAAuth
        from fastapi import Depends

        auth = UAAAuth()

        @app.get("/api/profile")
        async def profile(user = Depends(auth.get_current_user)):
            return {"user": user}
    """

    def __init__(self, base_url: str = "https://auth.opensora.store/api/v1"):
        """
        Initialize UAA Auth dependency

        Args:
            base_url: UAA API base URL
        """
        self.base_url = base_url
        self.client = httpx.AsyncClient(timeout=30.0)

    async def verify_token(self, token: str) -> Optional[User]:
        """
        Verify token and return user

        Args:
            token: Access token

        Returns:
            User object if valid, None otherwise
        """
        try:
            response = await self.client.get(
                f"{self.base_url}/auth/verify",
                headers={"Authorization": f"Bearer {token}"}
            )
            response.raise_for_status()
            data = response.json()
            return User(**data["user"])
        except httpx.HTTPError:
            return None

    async def get_current_user(
        self,
        authorization: Optional[str] = None
    ) -> User:
        """
        FastAPI dependency to get current user from Authorization header

        Args:
            authorization: Authorization header value

        Returns:
            User object

        Raises:
            HTTPException: If token is invalid or missing
        """
        from fastapi import HTTPException, Header

        if not authorization:
            raise HTTPException(status_code=401, detail="Missing authorization header")

        token = authorization.replace("Bearer ", "")
        user = await self.verify_token(token)

        if not user:
            raise HTTPException(status_code=401, detail="Invalid or expired token")

        return user
