"""
OAuth Token Monitoring Service
Service for creating and managing OAuth token monitoring tasks.
"""

from datetime import datetime, timedelta
from typing import List, Optional
from sqlalchemy.orm import Session
from utils.logger_utils import get_service_logger
import os

# Use service logger for consistent logging (WARNING level visible in production)
logger = get_service_logger("oauth_token_monitoring")

from models.oauth_token_monitoring_models import OAuthTokenMonitoringTask
from services.gsc_service import GSCService
from services.integrations.bing_oauth import BingOAuthService
from services.integrations.wordpress_oauth import WordPressOAuthService
from services.integrations.wix_oauth import WixOAuthService


def get_connected_platforms(user_id: str) -> List[str]:
    """
    Detect which platforms are connected for a user by checking token storage.
    
    Checks:
    - GSC: gsc_credentials table
    - Bing: bing_oauth_tokens table
    - WordPress: wordpress_oauth_tokens table
    - Wix: wix_oauth_tokens table
    
    Args:
        user_id: User ID (Clerk string)
        
    Returns:
        List of connected platform identifiers: ['gsc', 'bing', 'wordpress', 'wix']
    """
    connected = []
    
    # Use DEBUG level for routine checks (called frequently by dashboard)
    logger.debug(f"[OAuth Monitoring] Checking connected platforms for user: {user_id}")
    
    try:
        # Check GSC - use absolute database path
        db_path = os.path.abspath("alwrity.db")
        gsc_service = GSCService(db_path=db_path)
        gsc_credentials = gsc_service.load_user_credentials(user_id)
        if gsc_credentials:
            connected.append('gsc')
            logger.debug(f"[OAuth Monitoring] ✅ GSC connected for user {user_id}")
        else:
            logger.debug(f"[OAuth Monitoring] ❌ GSC not connected for user {user_id}")
    except Exception as e:
        logger.warning(f"[OAuth Monitoring] ⚠️ GSC check failed for user {user_id}: {e}", exc_info=True)
    
    try:
        # Check Bing - use absolute database path
        db_path = os.path.abspath("alwrity.db")
        bing_service = BingOAuthService(db_path=db_path)
        token_status = bing_service.get_user_token_status(user_id)
        has_active_tokens = token_status.get('has_active_tokens', False)
        has_expired_tokens = token_status.get('has_expired_tokens', False)
        expired_tokens = token_status.get('expired_tokens', [])
        
        # Check if expired tokens have refresh tokens (can be refreshed)
        has_refreshable_tokens = any(token.get('refresh_token') for token in expired_tokens)
        
        # Consider connected if user has active tokens OR expired tokens with refresh tokens
        if has_active_tokens or (has_expired_tokens and has_refreshable_tokens):
            connected.append('bing')
            logger.debug(f"[OAuth Monitoring] ✅ Bing connected for user {user_id}")
        else:
            logger.debug(f"[OAuth Monitoring] ❌ Bing not connected for user {user_id}")
    except Exception as e:
        logger.warning(f"[OAuth Monitoring] ⚠️ Bing check failed for user {user_id}: {e}", exc_info=True)
    
    try:
        # Check WordPress - use absolute database path
        db_path = os.path.abspath("alwrity.db")
        wordpress_service = WordPressOAuthService(db_path=db_path)
        token_status = wordpress_service.get_user_token_status(user_id)
        has_active_tokens = token_status.get('has_active_tokens', False)
        has_tokens = token_status.get('has_tokens', False)
        
        # Consider connected if user has any tokens (WordPress tokens may not have refresh tokens)
        # If tokens exist, user was connected even if expired (may need re-auth)
        if has_tokens:
            connected.append('wordpress')
            logger.debug(f"[OAuth Monitoring] ✅ WordPress connected for user {user_id}")
        else:
            logger.debug(f"[OAuth Monitoring] ❌ WordPress not connected for user {user_id}")
    except Exception as e:
        logger.warning(f"[OAuth Monitoring] ⚠️ WordPress check failed for user {user_id}: {e}", exc_info=True)
    
    try:
        # Check Wix - use absolute database path
        db_path = os.path.abspath("alwrity.db")
        wix_service = WixOAuthService(db_path=db_path)
        token_status = wix_service.get_user_token_status(user_id)
        has_active_tokens = token_status.get('has_active_tokens', False)
        has_expired_tokens = token_status.get('has_expired_tokens', False)
        expired_tokens = token_status.get('expired_tokens', [])
        
        # Check if expired tokens have refresh tokens (can be refreshed)
        has_refreshable_tokens = any(token.get('refresh_token') for token in expired_tokens)
        
        # Consider connected if user has active tokens OR expired tokens with refresh tokens
        if has_active_tokens or (has_expired_tokens and has_refreshable_tokens):
            connected.append('wix')
            logger.debug(f"[OAuth Monitoring] ✅ Wix connected for user {user_id}")
        else:
            logger.debug(f"[OAuth Monitoring] ❌ Wix not connected for user {user_id}")
    except Exception as e:
        logger.warning(f"[OAuth Monitoring] ⚠️ Wix check failed for user {user_id}: {e}", exc_info=True)
    
    # Don't log here - let the caller log a formatted summary if needed
    # This function is called frequently and should be silent
    return connected


def create_oauth_monitoring_tasks(
    user_id: str,
    db: Session,
    platforms: Optional[List[str]] = None
) -> List[OAuthTokenMonitoringTask]:
    """
    Create OAuth token monitoring tasks for a user.
    
    If platforms are not provided, automatically detects connected platforms.
    Creates one task per platform with next_check set to 7 days from now.
    
    Args:
        user_id: User ID (Clerk string)
        db: Database session
        platforms: Optional list of platforms to create tasks for.
                   If None, auto-detects connected platforms.
                   Valid values: 'gsc', 'bing', 'wordpress', 'wix'
        
    Returns:
        List of created OAuthTokenMonitoringTask instances
    """
    try:
        # Auto-detect platforms if not provided
        if platforms is None:
            platforms = get_connected_platforms(user_id)
            logger.warning(f"[OAuth Monitoring] Auto-detected {len(platforms)} connected platforms for user {user_id}: {platforms}")
        else:
            logger.warning(f"[OAuth Monitoring] Creating monitoring tasks for specified platforms: {platforms}")
        
        if not platforms:
            logger.warning(f"[OAuth Monitoring] No connected platforms found for user {user_id}. No monitoring tasks created.")
            return []
        
        created_tasks = []
        now = datetime.utcnow()
        next_check = now + timedelta(days=7)  # 7 days from now
        
        for platform in platforms:
            # Check if task already exists for this user/platform combination
            existing_task = db.query(OAuthTokenMonitoringTask).filter(
                OAuthTokenMonitoringTask.user_id == user_id,
                OAuthTokenMonitoringTask.platform == platform
            ).first()
            
            if existing_task:
                logger.warning(
                    f"[OAuth Monitoring] Monitoring task already exists for user {user_id}, platform {platform}. "
                    f"Skipping creation."
                )
                continue
            
            # Create new monitoring task
            task = OAuthTokenMonitoringTask(
                user_id=user_id,
                platform=platform,
                status='active',
                next_check=next_check,
                created_at=now,
                updated_at=now
            )
            
            db.add(task)
            created_tasks.append(task)
            logger.warning(
                f"[OAuth Monitoring] Created OAuth token monitoring task for user {user_id}, "
                f"platform {platform}, next_check: {next_check.isoformat()}"
            )
        
        db.commit()
        logger.warning(
            f"[OAuth Monitoring] Successfully created {len(created_tasks)} OAuth token monitoring tasks "
            f"for user {user_id}"
        )
        
        return created_tasks
        
    except Exception as e:
        logger.error(
            f"Error creating OAuth token monitoring tasks for user {user_id}: {e}",
            exc_info=True
        )
        db.rollback()
        return []

