"""
Authentication and token management
"""

import httpx
from typing import Optional
from datetime import datetime, timedelta
import jwt


class TokenManager:
    """Manages access tokens and refresh tokens"""
    
    def __init__(self, base_url: str, access_token: Optional[str] = None, refresh_token: Optional[str] = None):
        self.base_url = base_url.rstrip("/")
        self.access_token = access_token
        self.refresh_token = refresh_token
        self._token_expiry: Optional[datetime] = None
        
        if access_token:
            self._parse_token_expiry(access_token)
    
    def _parse_token_expiry(self, token: str):
        """Parse token expiry from JWT"""
        if jwt is None:
            # If PyJWT not available, assume token expires in 1 hour
            self._token_expiry = datetime.now() + timedelta(hours=1)
            return
        
        try:
            # Decode without verification to get expiry
            payload = jwt.decode(token, options={"verify_signature": False})
            exp = payload.get("exp")
            if exp:
                self._token_expiry = datetime.fromtimestamp(exp)
        except Exception:
            # If we can't parse, assume token expires in 1 hour
            self._token_expiry = datetime.now() + timedelta(hours=1)
    
    def is_token_expired(self, buffer_seconds: int = 60) -> bool:
        """Check if token is expired or will expire soon"""
        if not self._token_expiry:
            return True
        return datetime.now() >= (self._token_expiry - timedelta(seconds=buffer_seconds))
    
    def refresh_access_token(self) -> bool:
        """Refresh access token using refresh token"""
        if not self.refresh_token:
            return False
        
        try:
            with httpx.Client(base_url=self.base_url, timeout=30.0) as client:
                response = client.post(
                    "/v1/auth/refresh",
                    json={"refresh_token": self.refresh_token}
                )
                
                if response.status_code == 200:
                    data = response.json()
                    self.access_token = data.get("access_token")
                    self.refresh_token = data.get("refresh_token", self.refresh_token)
                    
                    if self.access_token:
                        self._parse_token_expiry(self.access_token)
                        return True
                
                return False
        except Exception:
            return False
    
    def get_valid_token(self) -> Optional[str]:
        """Get a valid access token, refreshing if necessary"""
        if not self.access_token:
            return None
        
        if self.is_token_expired():
            if not self.refresh_access_token():
                return None
        
        return self.access_token

