"""
User session management routes.
"""
from fastapi import APIRouter, Depends, HTTPException, Request, Response, Cookie
from sqlalchemy.orm import Session
from ...shared.config.database import get_db
from ...shared.config.logging_config import get_logger
from ...shared.config.settings import settings
from ...security.middleware.auth import get_current_user
from ...auth.models.user import User
from ...auth.models.user_session import UserSession
from ...auth.services.session_service import session_service
from ...shared.utils.response_helpers import success_response
from jose import jwt

logger = get_logger(__name__)
router = APIRouter(prefix='/sessions', tags=['sessions'])

@router.get('/')
async def get_my_sessions(
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """Get current user's active sessions."""
    try:
        sessions = session_service.get_user_sessions(
            db=db,
            user_id=current_user.id,
            active_only=True
        )
        
        return success_response(data={
            'sessions': [{
                'id': s.id,
                'ip_address': s.ip_address,
                'user_agent': s.user_agent,
                'device_info': s.device_info,
                'last_activity': s.last_activity.isoformat() if s.last_activity else None,
                'created_at': s.created_at.isoformat() if s.created_at else None,
                'expires_at': s.expires_at.isoformat() if s.expires_at else None
            } for s in sessions]
        })
    except Exception as e:
        logger.error(f'Error getting sessions: {str(e)}', exc_info=True)
        raise HTTPException(status_code=500, detail=str(e))

@router.delete('/{session_id}')
async def revoke_session(
    session_id: int,
    request: Request,
    response: Response,
    current_user: User = Depends(get_current_user),
    access_token: str = Cookie(None, alias='accessToken'),
    db: Session = Depends(get_db)
):
    """Revoke a specific session."""
    try:
        # Verify session belongs to user
        session = db.query(UserSession).filter(
            UserSession.id == session_id,
            UserSession.user_id == current_user.id
        ).first()
        
        if not session:
            raise HTTPException(status_code=404, detail='Session not found')
        
        # Check if this is the current session being revoked
        # We detect this by checking if:
        # 1. The session IP matches the request IP (if available)
        # 2. The session is the most recent active session
        is_current_session = False
        try:
            client_ip = request.client.host if request.client else None
            user_agent = request.headers.get('User-Agent', '')
            
            # Check if session matches current request characteristics
            if client_ip and session.ip_address == client_ip:
                # Also check if it's the most recent session
                recent_session = db.query(UserSession).filter(
                    UserSession.user_id == current_user.id,
                    UserSession.is_active == True
                ).order_by(UserSession.last_activity.desc()).first()
                
                if recent_session and recent_session.id == session_id:
                    is_current_session = True
        except Exception as e:
            logger.warning(f'Could not determine if session is current: {str(e)}')
            # If we can't determine, check if it's the only active session
            active_sessions_count = db.query(UserSession).filter(
                UserSession.user_id == current_user.id,
                UserSession.is_active == True
            ).count()
            if active_sessions_count <= 1:
                is_current_session = True
        
        success = session_service.revoke_session(db=db, session_token=session.session_token)
        if not success:
            raise HTTPException(status_code=404, detail='Session not found')
        
        # If this was the current session, clear cookies and indicate logout needed
        if is_current_session:
            from ...shared.config.settings import settings
            samesite_value = 'strict' if settings.is_production else 'lax'
            # Clear access token cookie
            response.delete_cookie(
                key='accessToken',
                path='/',
                samesite=samesite_value,
                secure=settings.is_production
            )
            # Clear refresh token cookie
            response.delete_cookie(
                key='refreshToken',
                path='/',
                samesite=samesite_value,
                secure=settings.is_production
            )
            return success_response(
                message='Session revoked successfully. You have been logged out.',
                data={'logout_required': True}
            )
        
        return success_response(message='Session revoked successfully')
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f'Error revoking session: {str(e)}', exc_info=True)
        raise HTTPException(status_code=500, detail=str(e))

@router.post('/revoke-all')
async def revoke_all_sessions(
    request: Request,
    response: Response,
    current_user: User = Depends(get_current_user),
    access_token: str = Cookie(None, alias='accessToken'),
    db: Session = Depends(get_db)
):
    """Revoke all sessions for current user."""
    try:
        count = session_service.revoke_all_user_sessions(
            db=db,
            user_id=current_user.id,
            exclude_token=None  # Don't exclude current session, revoke all
        )
        
        # Clear cookies since all sessions (including current) are revoked
        from ...shared.config.settings import settings
        samesite_value = 'strict' if settings.is_production else 'lax'
        # Clear access token cookie
        response.delete_cookie(
            key='accessToken',
            path='/',
            samesite=samesite_value,
            secure=settings.is_production
        )
        # Clear refresh token cookie
        response.delete_cookie(
            key='refreshToken',
            path='/',
            samesite=samesite_value,
            secure=settings.is_production
        )
        
        return success_response(
            data={'revoked_count': count, 'logout_required': True},
            message=f'Revoked {count} session(s). You have been logged out.'
        )
    except Exception as e:
        logger.error(f'Error revoking all sessions: {str(e)}', exc_info=True)
        raise HTTPException(status_code=500, detail=str(e))

