"""
OAuth authentication handlers for web dashboard
Supports Google, Facebook, Discord, and GitHub OAuth providers
"""

import logging
import secrets
import urllib.parse
from datetime import datetime, timedelta
from typing import Optional, Dict, Any
from flask import request, jsonify, redirect, session, g

from ..database.manager import DatabaseManager
from ..database.models import UserModel, OAuthProviderModel, UserOAuthAccountModel

logger = logging.getLogger(__name__)


class OAuthManager:
    """Handles OAuth authentication flows for multiple providers"""

    def __init__(self, db_manager: DatabaseManager, app=None):
        self.db_manager = db_manager
        self.app = app
        
        # OAuth state storage (in production, use Redis or database)
        self._oauth_states = {}
        
        logger.info("OAuthManager initialized")

    def get_provider_config(self, provider_name: str) -> Optional[Dict[str, Any]]:
        """Get OAuth provider configuration from database"""
        try:
            session = self.db_manager.get_session()
            try:
                provider = session.query(OAuthProviderModel).filter_by(
                    provider_name=provider_name.lower(),
                    is_active=True
                ).first()
                
                if provider:
                    return {
                        'id': provider.id,
                        'provider_name': provider.provider_name,
                        'display_name': provider.display_name,
                        'client_id': provider.client_id,
                        'client_secret': provider.client_secret,
                        'authorization_url': provider.authorization_url,
                        'token_url': provider.token_url,
                        'user_info_url': provider.user_info_url,
                        'scopes': provider.scopes.split() if provider.scopes else []
                    }
                return None
            finally:
                session.close()
        except Exception as e:
            logger.error(f"Failed to get provider config for {provider_name}: {e}")
            return None

    def get_authorization_url(self, provider_name: str, redirect_uri: str) -> Optional[str]:
        """Generate OAuth authorization URL for the specified provider"""
        try:
            config = self.get_provider_config(provider_name)
            if not config:
                logger.error(f"Provider {provider_name} not found or not active")
                return None
            
            # Generate state for CSRF protection
            state = secrets.token_urlsafe(32)
            self._oauth_states[state] = {
                'provider': provider_name,
                'redirect_uri': redirect_uri,
                'created_at': datetime.utcnow().isoformat()
            }
            
            # Build authorization URL
            params = {
                'client_id': config['client_id'],
                'redirect_uri': redirect_uri,
                'response_type': 'code',
                'scope': ' '.join(config['scopes']),
                'state': state
            }
            
            # Provider-specific parameters
            # Note: We don't force 'prompt=consent' to allow seamless login for returning users
            # The OAuth provider will remember the user's previous consent
            if provider_name.lower() == 'google':
                params['access_type'] = 'offline'
                # Use 'select_account' to allow account switching without forcing consent
                # Remove this line entirely for completely seamless login
                params['prompt'] = 'select_account'
            elif provider_name.lower() == 'facebook':
                # Don't use 'rerequest' for normal logins - only use when permissions were declined
                pass
            elif provider_name.lower() == 'discord':
                # Don't force consent - allow returning users to login seamlessly
                pass
            
            authorization_url = f"{config['authorization_url']}?{urllib.parse.urlencode(params)}"
            
            logger.info(f"Generated authorization URL for {provider_name}")
            return authorization_url
            
        except Exception as e:
            logger.error(f"Failed to generate authorization URL for {provider_name}: {e}")
            return None

    def exchange_code_for_token(self, provider_name: str, code: str, redirect_uri: str) -> Optional[Dict[str, Any]]:
        """Exchange authorization code for access token"""
        try:
            import requests
            
            config = self.get_provider_config(provider_name)
            if not config:
                logger.error(f"Provider {provider_name} not found or not active")
                return None
            
            # Prepare token request
            token_data = {
                'client_id': config['client_id'],
                'client_secret': config['client_secret'],
                'code': code,
                'redirect_uri': redirect_uri,
                'grant_type': 'authorization_code'
            }
            
            headers = {
                'Accept': 'application/json',
                'Content-Type': 'application/x-www-form-urlencoded'
            }
            
            # Provider-specific adjustments
            if provider_name.lower() == 'github':
                headers['Accept'] = 'application/json'
            
            response = requests.post(config['token_url'], data=token_data, headers=headers)
            
            if response.status_code != 200:
                logger.error(f"Token exchange failed for {provider_name}: {response.status_code} - {response.text}")
                return None
            
            token_response = response.json()
            
            logger.info(f"Successfully exchanged code for token for {provider_name}")
            return token_response
            
        except Exception as e:
            logger.error(f"Failed to exchange code for token for {provider_name}: {e}")
            return None

    def get_user_info(self, provider_name: str, access_token: str) -> Optional[Dict[str, Any]]:
        """Get user information from OAuth provider"""
        try:
            import requests
            
            config = self.get_provider_config(provider_name)
            if not config:
                logger.error(f"Provider {provider_name} not found or not active")
                return None
            
            headers = {
                'Authorization': f'Bearer {access_token}',
                'Accept': 'application/json'
            }
            
            response = requests.get(config['user_info_url'], headers=headers)
            
            if response.status_code != 200:
                logger.error(f"Failed to get user info from {provider_name}: {response.status_code}")
                return None
            
            user_info = response.json()
            
            # Normalize user info across providers
            normalized_info = self._normalize_user_info(provider_name, user_info)
            
            logger.info(f"Successfully retrieved user info from {provider_name}")
            return normalized_info
            
        except Exception as e:
            logger.error(f"Failed to get user info from {provider_name}: {e}")
            return None

    def _normalize_user_info(self, provider_name: str, user_info: Dict[str, Any]) -> Dict[str, Any]:
        """Normalize user info from different providers to a common format"""
        normalized = {
            'provider': provider_name,
            'raw_info': user_info
        }
        
        if provider_name.lower() == 'google':
            normalized.update({
                'provider_user_id': user_info.get('id'),
                'email': user_info.get('email'),
                'name': user_info.get('name'),
                'given_name': user_info.get('given_name'),
                'family_name': user_info.get('family_name'),
                'picture': user_info.get('picture'),
                'email_verified': user_info.get('verified_email', False)
            })
        
        elif provider_name.lower() == 'facebook':
            normalized.update({
                'provider_user_id': user_info.get('id'),
                'email': user_info.get('email'),
                'name': user_info.get('name'),
                'first_name': user_info.get('first_name'),
                'last_name': user_info.get('last_name'),
                'picture': user_info.get('picture', {}).get('data', {}).get('url') if user_info.get('picture') else None
            })
        
        elif provider_name.lower() == 'discord':
            normalized.update({
                'provider_user_id': user_info.get('id'),
                'email': user_info.get('email'),
                'name': user_info.get('global_name') or user_info.get('username'),
                'username': user_info.get('username'),
                'discriminator': user_info.get('discriminator'),
                'avatar': user_info.get('avatar'),
                'email_verified': user_info.get('verified', False)
            })
        
        elif provider_name.lower() == 'github':
            normalized.update({
                'provider_user_id': str(user_info.get('id')),
                'email': user_info.get('email'),
                'name': user_info.get('name'),
                'username': user_info.get('login'),
                'avatar_url': user_info.get('avatar_url'),
                'bio': user_info.get('bio')
            })
        
        return normalized

    def verify_state(self, state: str) -> Optional[Dict[str, Any]]:
        """Verify OAuth state and return stored data"""
        state_data = self._oauth_states.get(state)
        if state_data:
            # Check if state is not too old (5 minutes max)
            created_at = datetime.fromisoformat(state_data['created_at'])
            if datetime.utcnow() - created_at < timedelta(minutes=5):
                # Remove used state
                del self._oauth_states[state]
                return state_data
        return None

    def find_user_by_oauth(self, provider_name: str, provider_user_id: str) -> Optional[UserModel]:
        """Find user by OAuth provider and provider user ID"""
        try:
            session = self.db_manager.get_session()
            try:
                # Get provider
                provider = session.query(OAuthProviderModel).filter_by(
                    provider_name=provider_name.lower()
                ).first()
                
                if not provider:
                    return None
                
                # Find OAuth account
                oauth_account = session.query(UserOAuthAccountModel).filter_by(
                    provider_id=provider.id,
                    provider_user_id=provider_user_id,
                    is_active=True
                ).first()
                
                if oauth_account:
                    # Get user
                    user = session.query(UserModel).filter_by(id=oauth_account.user_id).first()
                    return user
                
                return None
            finally:
                session.close()
        except Exception as e:
            logger.error(f"Failed to find user by OAuth: {e}")
            return None

    def find_user_by_email(self, email: str) -> Optional[UserModel]:
        """Find user by email address"""
        try:
            return self.db_manager.get_user_by_email(email)
        except Exception as e:
            logger.error(f"Failed to find user by email: {e}")
            return None

    def link_oauth_account(self, user_id: int, provider_name: str, provider_user_id: str,
                          provider_email: str = None, provider_name_value: str = None,
                          access_token: str = None, refresh_token: str = None,
                          token_expires_at: datetime = None) -> bool:
        """Link OAuth account to existing user"""
        try:
            session = self.db_manager.get_session()
            try:
                # Get provider
                provider = session.query(OAuthProviderModel).filter_by(
                    provider_name=provider_name.lower()
                ).first()
                
                if not provider:
                    logger.error(f"Provider {provider_name} not found")
                    return False
                
                # Check if already linked
                existing = session.query(UserOAuthAccountModel).filter_by(
                    user_id=user_id,
                    provider_id=provider.id
                ).first()
                
                if existing:
                    # Update existing link
                    existing.provider_user_id = provider_user_id
                    existing.provider_email = provider_email
                    existing.provider_name = provider_name_value
                    existing.access_token = access_token
                    existing.refresh_token = refresh_token
                    existing.token_expires_at = token_expires_at
                    existing.last_used_at = datetime.utcnow()
                    existing.is_active = True
                else:
                    # Create new link
                    oauth_account = UserOAuthAccountModel(
                        user_id=user_id,
                        provider_id=provider.id,
                        provider_user_id=provider_user_id,
                        provider_email=provider_email,
                        provider_name=provider_name_value,
                        access_token=access_token,
                        refresh_token=refresh_token,
                        token_expires_at=token_expires_at,
                        is_active=True,
                        last_used_at=datetime.utcnow()
                    )
                    session.add(oauth_account)
                
                session.commit()
                logger.info(f"Linked {provider_name} account to user {user_id}")
                return True
                
            finally:
                session.close()
        except Exception as e:
            logger.error(f"Failed to link OAuth account: {e}")
            return False

    def create_user_from_oauth(self, provider_name: str, user_info: Dict[str, Any],
                               access_token: str = None, refresh_token: str = None,
                               token_expires_at: datetime = None, role: str = 'player') -> Optional[UserModel]:
        """Create new user from OAuth information"""
        try:
            import hashlib
            import secrets as sec
            
            email = user_info.get('email')
            name = user_info.get('name', '')
            
            if not email:
                logger.error("Cannot create user without email from OAuth")
                return None
            
            # Generate username from email or name
            base_username = email.split('@')[0].lower()
            username = base_username
            
            # Ensure unique username
            counter = 1
            while self.db_manager.get_user_by_username(username):
                username = f"{base_username}_{counter}"
                counter += 1
            
            # Generate random password (user will need to set it later if they want password login)
            random_password = sec.token_urlsafe(32)
            salt = sec.token_hex(16)
            password_hash = hashlib.sha256((random_password + salt).encode()).hexdigest()
            stored_hash = f"{salt}:{password_hash}"
            
            # Create user
            session = self.db_manager.get_session()
            try:
                user = UserModel(
                    username=username,
                    email=email,
                    password_hash=stored_hash,
                    is_active=True,
                    is_admin=False,
                    role=role,
                    email_verified=user_info.get('email_verified', True),
                    email_verified_at=datetime.utcnow() if user_info.get('email_verified') else None
                )
                session.add(user)
                session.commit()
                session.refresh(user)
                
                # Link OAuth account
                self.link_oauth_account(
                    user_id=user.id,
                    provider_name=provider_name,
                    provider_user_id=user_info.get('provider_user_id'),
                    provider_email=email,
                    provider_name_value=name,
                    access_token=access_token,
                    refresh_token=refresh_token,
                    token_expires_at=token_expires_at
                )
                
                logger.info(f"Created new user from {provider_name} OAuth: {username}")
                return user
                
            finally:
                session.close()
                
        except Exception as e:
            logger.error(f"Failed to create user from OAuth: {e}")
            return None

    def get_available_providers(self) -> list:
        """Get list of available and configured OAuth providers"""
        try:
            session = self.db_manager.get_session()
            try:
                providers = session.query(OAuthProviderModel).filter_by(
                    is_active=True
                ).all()
                
                result = []
                for provider in providers:
                    # Check if provider is configured (has client_id and client_secret)
                    is_configured = bool(provider.client_id and provider.client_secret)
                    result.append({
                        'name': provider.provider_name,
                        'display_name': provider.display_name,
                        'is_configured': is_configured
                    })
                
                return result
            finally:
                session.close()
        except Exception as e:
            logger.error(f"Failed to get available providers: {e}")
            return []

    def unlink_oauth_account(self, user_id: int, provider_name: str) -> bool:
        """Unlink OAuth account from user"""
        try:
            session = self.db_manager.get_session()
            try:
                # Get provider
                provider = session.query(OAuthProviderModel).filter_by(
                    provider_name=provider_name.lower()
                ).first()
                
                if not provider:
                    return False
                
                # Find and deactivate OAuth account
                oauth_account = session.query(UserOAuthAccountModel).filter_by(
                    user_id=user_id,
                    provider_id=provider.id
                ).first()
                
                if oauth_account:
                    oauth_account.is_active = False
                    session.commit()
                    logger.info(f"Unlinked {provider_name} account from user {user_id}")
                    return True
                
                return False
            finally:
                session.close()
        except Exception as e:
            logger.error(f"Failed to unlink OAuth account: {e}")
            return False


# Flask route handlers for OAuth
def init_oauth_routes(app, oauth_manager: OAuthManager, auth_manager):
    """Initialize OAuth routes for Flask app"""
    
    @app.route('/api/oauth-config', methods=['GET'])
    def get_oauth_config_public():
        """Get OAuth configuration for frontend (public endpoint)"""
        try:
            providers = oauth_manager.get_available_providers()
            result = {}
            for p in providers:
                config = oauth_manager.get_provider_config(p['name'])
                if config and p['is_configured']:
                    result[p['name']] = {
                        'enabled': True,
                        'clientId': config['client_id'],
                        'displayName': config['display_name']
                    }
                else:
                    result[p['name']] = {
                        'enabled': False
                    }
            
            # Also include providers that exist but aren't configured
            for provider_name in ['google', 'facebook', 'discord']:
                if provider_name not in result:
                    result[provider_name] = {'enabled': False}
            
            return jsonify(result)
        except Exception as e:
            logger.error(f"Failed to get OAuth config: {e}")
            # Return default config with all providers disabled
            return jsonify({
                'google': {'enabled': False},
                'facebook': {'enabled': False},
                'discord': {'enabled': False}
            })
    
    @app.route('/api/oauth/config/<provider_name>', methods=['GET'])
    def get_oauth_provider_config(provider_name):
        """Get OAuth configuration for a specific provider (public endpoint)"""
        try:
            config = oauth_manager.get_provider_config(provider_name)
            
            if config:
                return jsonify({
                    'enabled': True,
                    'clientId': config['client_id'],
                    'displayName': config['display_name'],
                    'scopes': config['scopes']
                })
            else:
                return jsonify({
                    'enabled': False,
                    'error': f'Provider {provider_name} not configured'
                })
        except Exception as e:
            logger.error(f"Failed to get OAuth config for {provider_name}: {e}")
            return jsonify({'enabled': False, 'error': str(e)})
    
    @app.route('/api/oauth/providers', methods=['GET'])
    def get_oauth_providers():
        """Get list of available OAuth providers"""
        try:
            providers = oauth_manager.get_available_providers()
            return jsonify({
                'success': True,
                'providers': providers
            })
        except Exception as e:
            logger.error(f"Failed to get OAuth providers: {e}")
            return jsonify({'error': str(e)}), 500
    
    @app.route('/api/oauth/<provider_name>/authorize', methods=['GET'])
    def oauth_authorize(provider_name):
        """Initiate OAuth authorization flow"""
        try:
            redirect_uri = request.args.get('redirect_uri')
            if not redirect_uri:
                # Use default redirect URI
                redirect_uri = request.host_url.rstrip('/') + '/api/oauth/' + provider_name + '/callback'
            
            authorization_url = oauth_manager.get_authorization_url(provider_name, redirect_uri)
            
            if authorization_url:
                return jsonify({
                    'success': True,
                    'authorization_url': authorization_url
                })
            else:
                return jsonify({'error': f'Provider {provider_name} not available'}), 400
                
        except Exception as e:
            logger.error(f"OAuth authorization error: {e}")
            return jsonify({'error': str(e)}), 500
    
    @app.route('/api/oauth/<provider_name>/callback', methods=['GET'])
    def oauth_callback(provider_name):
        """Handle OAuth callback (GET - redirect from provider)"""
        try:
            code = request.args.get('code')
            state = request.args.get('state')
            error = request.args.get('error')
            
            if error:
                logger.error(f"OAuth error from {provider_name}: {error}")
                return redirect(f"/login?oauth_error={error}")
            
            if not code:
                return jsonify({'error': 'No authorization code received'}), 400
            
            # Verify state
            state_data = oauth_manager.verify_state(state)
            if not state_data:
                return jsonify({'error': 'Invalid or expired state'}), 400
            
            redirect_uri = request.host_url.rstrip('/') + '/api/oauth/' + provider_name + '/callback'
            
            # Exchange code for token
            token_data = oauth_manager.exchange_code_for_token(provider_name, code, redirect_uri)
            if not token_data:
                return jsonify({'error': 'Failed to exchange authorization code'}), 400
            
            access_token = token_data.get('access_token')
            refresh_token = token_data.get('refresh_token')
            expires_in = token_data.get('expires_in')
            token_expires_at = datetime.utcnow() + timedelta(seconds=expires_in) if expires_in else None
            
            # Get user info
            user_info = oauth_manager.get_user_info(provider_name, access_token)
            if not user_info:
                return jsonify({'error': 'Failed to get user information'}), 400
            
            # Find or create user
            user = oauth_manager.find_user_by_oauth(provider_name, user_info.get('provider_user_id'))
            
            if not user:
                # Try to find by email
                email = user_info.get('email')
                if email:
                    user = oauth_manager.find_user_by_email(email)
                    
                    if user:
                        # Link OAuth account to existing user
                        oauth_manager.link_oauth_account(
                            user_id=user.id,
                            provider_name=provider_name,
                            provider_user_id=user_info.get('provider_user_id'),
                            provider_email=email,
                            provider_name_value=user_info.get('name'),
                            access_token=access_token,
                            refresh_token=refresh_token,
                            token_expires_at=token_expires_at
                        )
            
            if not user:
                # Create new user
                user = oauth_manager.create_user_from_oauth(
                    provider_name=provider_name,
                    user_info=user_info,
                    access_token=access_token,
                    refresh_token=refresh_token,
                    token_expires_at=token_expires_at
                )
            
            if user:
                # Create JWT token for the user (with refresh token for persistent session)
                token_data = auth_manager.create_jwt_token(user.id, include_refresh=True)
                
                if token_data:
                    # Redirect to frontend with tokens
                    frontend_url = app.config.get('FRONTEND_URL', '/')
                    redirect_url = f"{frontend_url}?oauth_token={token_data['access_token']}&refresh_token={token_data['refresh_token']}&provider={provider_name}"
                    return redirect(redirect_url)
                else:
                    return jsonify({'error': 'Failed to create authentication token'}), 500
            else:
                return jsonify({'error': 'Failed to create or find user'}), 400
                
        except Exception as e:
            logger.error(f"OAuth callback error: {e}")
            return jsonify({'error': str(e)}), 500
    
    @app.route('/api/oauth/callback/<provider_name>', methods=['POST'])
    def oauth_callback_post(provider_name):
        """Handle OAuth callback (POST - from frontend with code)"""
        try:
            data = request.get_json() or {}
            code = data.get('code')
            state = data.get('state')
            role = data.get('role', 'player')
            
            if not code:
                return jsonify({'error': 'No authorization code received'}), 400
            
            # Verify state if provided
            if state:
                state_data = oauth_manager.verify_state(state)
                if not state_data:
                    return jsonify({'error': 'Invalid or expired state'}), 400
            
            # Build redirect URI (must match what was used in authorization)
            redirect_uri = request.host_url.rstrip('/') + '/api/oauth/callback/' + provider_name
            
            # Exchange code for token
            token_data = oauth_manager.exchange_code_for_token(provider_name, code, redirect_uri)
            if not token_data:
                return jsonify({'error': 'Failed to exchange authorization code'}), 400
            
            access_token = token_data.get('access_token')
            refresh_token = token_data.get('refresh_token')
            expires_in = token_data.get('expires_in')
            token_expires_at = datetime.utcnow() + timedelta(seconds=expires_in) if expires_in else None
            
            # Get user info
            user_info = oauth_manager.get_user_info(provider_name, access_token)
            if not user_info:
                return jsonify({'error': 'Failed to get user information'}), 400
            
            # Find or create user
            user = oauth_manager.find_user_by_oauth(provider_name, user_info.get('provider_user_id'))
            
            if not user:
                # Try to find by email
                email = user_info.get('email')
                if email:
                    user = oauth_manager.find_user_by_email(email)
                    
                    if user:
                        # Link OAuth account to existing user
                        oauth_manager.link_oauth_account(
                            user_id=user.id,
                            provider_name=provider_name,
                            provider_user_id=user_info.get('provider_user_id'),
                            provider_email=email,
                            provider_name_value=user_info.get('name'),
                            access_token=access_token,
                            refresh_token=refresh_token,
                            token_expires_at=token_expires_at
                        )
            
            if not user:
                # Create new user with specified role
                user = oauth_manager.create_user_from_oauth(
                    provider_name=provider_name,
                    user_info=user_info,
                    access_token=access_token,
                    refresh_token=refresh_token,
                    token_expires_at=token_expires_at,
                    role=role
                )
            
            if user:
                # Create JWT token for the user (with refresh token for persistent session)
                token_data = auth_manager.create_jwt_token(user.id, include_refresh=True)
                
                if token_data:
                    # Return user info and tokens
                    return jsonify({
                        'success': True,
                        'access_token': token_data['access_token'],
                        'refresh_token': token_data['refresh_token'],
                        'expires_in': token_data['expires_in'],
                        'token_type': token_data['token_type'],
                        'user': {
                            'id': user.id,
                            'username': user.username,
                            'email': user.email,
                            'role': user.role,
                            'is_admin': user.is_admin
                        }
                    })
                else:
                    return jsonify({'error': 'Failed to create authentication token'}), 500
            else:
                return jsonify({'error': 'Failed to create or find user'}), 400
                
        except Exception as e:
            logger.error(f"OAuth callback POST error: {e}")
            return jsonify({'error': str(e)}), 500
    
    @app.route('/api/oauth/<provider_name>/link', methods=['POST'])
    def link_oauth_provider(provider_name):
        """Link OAuth provider to existing account (requires authentication)"""
        try:
            from .auth import require_api_auth
            
            @require_api_auth
            def _link():
                current_user = request.current_user
                user_id = current_user.get('user_id')
                
                code = request.json.get('code')
                redirect_uri = request.json.get('redirect_uri')
                
                if not code:
                    return jsonify({'error': 'Authorization code required'}), 400
                
                # Exchange code for token
                token_data = oauth_manager.exchange_code_for_token(provider_name, code, redirect_uri)
                if not token_data:
                    return jsonify({'error': 'Failed to exchange authorization code'}), 400
                
                access_token = token_data.get('access_token')
                refresh_token = token_data.get('refresh_token')
                expires_in = token_data.get('expires_in')
                token_expires_at = datetime.utcnow() + timedelta(seconds=expires_in) if expires_in else None
                
                # Get user info
                user_info = oauth_manager.get_user_info(provider_name, access_token)
                if not user_info:
                    return jsonify({'error': 'Failed to get user information'}), 400
                
                # Link account
                success = oauth_manager.link_oauth_account(
                    user_id=user_id,
                    provider_name=provider_name,
                    provider_user_id=user_info.get('provider_user_id'),
                    provider_email=user_info.get('email'),
                    provider_name_value=user_info.get('name'),
                    access_token=access_token,
                    refresh_token=refresh_token,
                    token_expires_at=token_expires_at
                )
                
                if success:
                    return jsonify({
                        'success': True,
                        'message': f'{provider_name.capitalize()} account linked successfully'
                    })
                else:
                    return jsonify({'error': 'Failed to link account'}), 400
            
            return _link()
                
        except Exception as e:
            logger.error(f"OAuth link error: {e}")
            return jsonify({'error': str(e)}), 500
    
    @app.route('/api/oauth/<provider_name>/unlink', methods=['POST'])
    def unlink_oauth_provider(provider_name):
        """Unlink OAuth provider from account (requires authentication)"""
        try:
            from .auth import require_api_auth
            
            @require_api_auth
            def _unlink():
                current_user = request.current_user
                user_id = current_user.get('user_id')
                
                success = oauth_manager.unlink_oauth_account(user_id, provider_name)
                
                if success:
                    return jsonify({
                        'success': True,
                        'message': f'{provider_name.capitalize()} account unlinked successfully'
                    })
                else:
                    return jsonify({'error': 'Failed to unlink account'}), 400
            
            return _unlink()
                
        except Exception as e:
            logger.error(f"OAuth unlink error: {e}")
            return jsonify({'error': str(e)}), 500
    
    @app.route('/api/auth/refresh', methods=['POST'])
    def refresh_token():
        """Refresh access token using refresh token for persistent sessions"""
        try:
            data = request.get_json() or {}
            refresh_token_value = data.get('refresh_token')
            
            if not refresh_token_value:
                return jsonify({'error': 'Refresh token required'}), 400
            
            # Use auth_manager to refresh the token
            token_data = auth_manager.refresh_jwt_token(refresh_token_value)
            
            if token_data:
                return jsonify({
                    'success': True,
                    'access_token': token_data['access_token'],
                    'expires_in': token_data['expires_in'],
                    'token_type': token_data['token_type']
                })
            else:
                return jsonify({'error': 'Invalid or expired refresh token'}), 401
                
        except Exception as e:
            logger.error(f"Token refresh error: {e}")
            return jsonify({'error': str(e)}), 500
    
    @app.route('/api/auth/logout', methods=['POST'])
    def logout():
        """Logout user by revoking their tokens"""
        try:
            from .auth import require_api_auth
            
            @require_api_auth
            def _logout():
                current_user = request.current_user
                
                # Revoke the access token
                auth_header = request.headers.get('Authorization')
                if auth_header and auth_header.startswith('Bearer '):
                    token = auth_header.split(' ', 1)[1]
                    auth_manager.revoke_jwt_token(token)
                
                # Also revoke refresh token if provided
                data = request.get_json() or {}
                refresh_token_value = data.get('refresh_token')
                if refresh_token_value:
                    auth_manager.revoke_jwt_token(refresh_token_value)
                
                return jsonify({
                    'success': True,
                    'message': 'Logged out successfully'
                })
            
            return _logout()
                
        except Exception as e:
            logger.error(f"Logout error: {e}")
            return jsonify({'error': str(e)}), 500
    
    logger.info("OAuth routes initialized")