"""
API key management routes.
"""
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from typing import List, Optional
from datetime import datetime
from ...shared.config.database import get_db
from ...shared.config.logging_config import get_logger
from ...security.middleware.auth import get_current_user, authorize_roles
from ...auth.models.user import User
from ..services.api_key_service import api_key_service
from ..models.api_key import APIKey
from ...shared.utils.response_helpers import success_response
from pydantic import BaseModel

logger = get_logger(__name__)
router = APIRouter(prefix='/api-keys', tags=['api-keys'])

class CreateAPIKeyRequest(BaseModel):
    name: str
    scopes: List[str]
    description: Optional[str] = None
    rate_limit: int = 100
    expires_at: Optional[str] = None

class UpdateAPIKeyRequest(BaseModel):
    name: Optional[str] = None
    scopes: Optional[List[str]] = None
    description: Optional[str] = None
    rate_limit: Optional[int] = None
    expires_at: Optional[str] = None

@router.post('/')
async def create_api_key(
    key_data: CreateAPIKeyRequest,
    current_user: User = Depends(authorize_roles('admin')),
    db: Session = Depends(get_db)
):
    """Create a new API key."""
    try:
        from sqlalchemy.exc import ProgrammingError
        import pymysql
        
        expires_at = None
        if key_data.expires_at:
            expires_at = datetime.fromisoformat(key_data.expires_at.replace('Z', '+00:00'))
        
        api_key, plain_key = api_key_service.create_api_key(
            db=db,
            name=key_data.name,
            scopes=key_data.scopes,
            created_by=current_user.id,
            description=key_data.description,
            rate_limit=key_data.rate_limit,
            expires_at=expires_at
        )
        
        return success_response(
            data={
                'api_key': {
                    'id': api_key.id,
                    'name': api_key.name,
                    'key_prefix': api_key.key_prefix,
                    'scopes': api_key.scopes,
                    'rate_limit': api_key.rate_limit,
                    'expires_at': api_key.expires_at.isoformat() if api_key.expires_at else None
                },
                'key': plain_key  # Return plain key only on creation
            },
            message='API key created successfully. Save this key securely - it will not be shown again.'
        )
    except HTTPException:
        raise
    except (ProgrammingError, pymysql.err.ProgrammingError) as e:
        error_str = str(e).lower()
        if "doesn't exist" in error_str or "does not exist" in error_str or "table" in error_str and "not found" in error_str:
            logger.warning(f'API keys table does not exist: {str(e)}')
            raise HTTPException(
                status_code=503,
                detail='API keys table not found. Please run database migrations to create the table.'
            )
        raise
    except Exception as e:
        logger.error(f'Error creating API key: {str(e)}', exc_info=True)
        raise HTTPException(status_code=500, detail=str(e))

@router.get('/')
async def get_api_keys(
    current_user: User = Depends(authorize_roles('admin')),
    db: Session = Depends(get_db)
):
    """Get all API keys."""
    try:
        from sqlalchemy.exc import ProgrammingError
        import pymysql
        
        api_keys = db.query(APIKey).order_by(APIKey.created_at.desc()).all()
        
        return success_response(data={
            'api_keys': [{
                'id': k.id,
                'name': k.name,
                'key_prefix': k.key_prefix,
                'scopes': k.scopes,
                'rate_limit': k.rate_limit,
                'is_active': k.is_active,
                'last_used_at': k.last_used_at.isoformat() if k.last_used_at else None,
                'expires_at': k.expires_at.isoformat() if k.expires_at else None,
                'created_at': k.created_at.isoformat() if k.created_at else None
            } for k in api_keys]
        })
    except (ProgrammingError, pymysql.err.ProgrammingError) as e:
        error_str = str(e).lower()
        if "doesn't exist" in error_str or "does not exist" in error_str or "table" in error_str and "not found" in error_str:
            logger.warning(f'API keys table does not exist: {str(e)}')
            return success_response(data={'api_keys': []}, message='API keys table not found. Please run database migrations.')
        raise
    except Exception as e:
        logger.error(f'Error getting API keys: {str(e)}', exc_info=True)
        raise HTTPException(status_code=500, detail=str(e))

@router.put('/{key_id}')
async def update_api_key(
    key_id: int,
    key_data: UpdateAPIKeyRequest,
    current_user: User = Depends(authorize_roles('admin')),
    db: Session = Depends(get_db)
):
    """Update an API key."""
    try:
        expires_at = None
        if key_data.expires_at:
            expires_at = datetime.fromisoformat(key_data.expires_at.replace('Z', '+00:00'))
        
        api_key = api_key_service.update_api_key(
            db=db,
            key_id=key_id,
            name=key_data.name,
            scopes=key_data.scopes,
            description=key_data.description,
            rate_limit=key_data.rate_limit,
            expires_at=expires_at
        )
        
        if not api_key:
            raise HTTPException(status_code=404, detail='API key not found')
        
        return success_response(
            data={
                'api_key': {
                    'id': api_key.id,
                    'name': api_key.name,
                    'key_prefix': api_key.key_prefix,
                    'scopes': api_key.scopes,
                    'rate_limit': api_key.rate_limit,
                    'is_active': api_key.is_active,
                    'expires_at': api_key.expires_at.isoformat() if api_key.expires_at else None,
                    'created_at': api_key.created_at.isoformat() if api_key.created_at else None
                }
            },
            message='API key updated successfully'
        )
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f'Error updating API key: {str(e)}', exc_info=True)
        raise HTTPException(status_code=500, detail=str(e))

@router.delete('/{key_id}')
async def revoke_api_key(
    key_id: int,
    current_user: User = Depends(authorize_roles('admin')),
    db: Session = Depends(get_db)
):
    """Revoke an API key."""
    try:
        success = api_key_service.revoke_api_key(db=db, key_id=key_id)
        if not success:
            raise HTTPException(status_code=404, detail='API key not found')
        
        return success_response(message='API key revoked successfully')
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f'Error revoking API key: {str(e)}', exc_info=True)
        raise HTTPException(status_code=500, detail=str(e))

