"""API key authentication."""
import hmac
from datetime import datetime, timedelta
from typing import Optional, Tuple, Dict
from api.utils import hash_api_key
from api.firestore_db import (
    get_api_key, update_api_key, get_organization, get_project
)


def verify_api_key(api_key: str) -> Optional[Dict]:
    """Verify API key and return the key entity if valid."""
    key_hash = hash_api_key(api_key)
    
    api_key_obj = get_api_key(key_hash)
    
    if not api_key_obj:
        return None
    
    # Check if revoked
    if api_key_obj.get('revoked_at'):
        return None
    
    # Check rate limit
    now = datetime.utcnow()
    rate_limit_reset = api_key_obj.get('rate_limit_reset')
    if rate_limit_reset:
        # Handle Firestore timestamp objects
        if hasattr(rate_limit_reset, 'timestamp'):
            # Firestore timestamp - convert to datetime
            rate_limit_reset = datetime.fromtimestamp(rate_limit_reset.timestamp())
        elif isinstance(rate_limit_reset, str):
            # String datetime - parse it
            try:
                # Try ISO format first
                rate_limit_reset = datetime.fromisoformat(rate_limit_reset.replace('Z', '+00:00'))
            except:
                # Fallback to basic parsing
                try:
                    # Try common formats
                    for fmt in ['%Y-%m-%d %H:%M:%S', '%Y-%m-%dT%H:%M:%S', '%Y-%m-%dT%H:%M:%S.%f']:
                        try:
                            rate_limit_reset = datetime.strptime(rate_limit_reset, fmt)
                            break
                        except:
                            continue
                    if isinstance(rate_limit_reset, str):
                        rate_limit_reset = None
                except:
                    rate_limit_reset = None
    
    if not rate_limit_reset or rate_limit_reset < now:
        # Reset rate limit window
        api_key_obj['request_count'] = 0
        api_key_obj['rate_limit_reset'] = now + timedelta(hours=1)
    
    if api_key_obj.get('request_count', 0) >= api_key_obj.get('rate_limit', 100):
        return None  # Rate limited
    
    # Update usage
    api_key_obj['request_count'] = api_key_obj.get('request_count', 0) + 1
    api_key_obj['last_used'] = now
    update_api_key(api_key_obj['id'], {
        'request_count': api_key_obj['request_count'],
        'last_used': api_key_obj['last_used'],
        'rate_limit_reset': api_key_obj['rate_limit_reset']
    })
    
    return api_key_obj


def get_organization_and_project(api_key_obj: Dict) -> Tuple[Optional[Dict], Optional[Dict]]:
    """Get organization and project for API key."""
    org = get_organization(api_key_obj['organization_id'])
    project = None
    if api_key_obj.get('project_id'):
        project = get_project(api_key_obj['project_id'])
    return org, project

