"""
Main MCP Server for League Analysis using FastMCP 2.0
"""

import json
import logging
from pathlib import Path
from typing import Dict, Any

from fastmcp import FastMCP

from .enhanced_auth import get_enhanced_auth_manager
from .cache import get_cache_manager
from .tools import register_tools
from .team_tools import register_team_tools
from .player_tools import register_player_tools
from .game_tools import register_game_tools
from .utility_tools import register_utility_tools
from .resources import register_resources
from .oauth_callback_server import automated_oauth_flow

# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# Load configuration
config_path = Path(__file__).parent / "config" / "settings.json"
with open(config_path) as f:
    config = json.load(f)

# Load game ID mappings
game_ids_path = Path(__file__).parent / "config" / "game_ids.json"
with open(game_ids_path) as f:
    game_ids = json.load(f)

# Initialize FastMCP server
mcp = FastMCP(
    name=config["server"]["name"],
    version=config["server"]["version"],
    description=config["server"]["description"]
)

# Global state
app_state = {
    "auth_manager": get_enhanced_auth_manager(),
    "cache_manager": get_cache_manager(),
    "config": config,
    "game_ids": game_ids
}


@mcp.tool()
def get_server_info() -> Dict[str, Any]:
    """
    Get information about the League Analysis MCP server.

    Returns:
        Server configuration and status information
    """
    auth_manager = app_state["auth_manager"]
    cache_manager = app_state["cache_manager"]

    return {
        "server": config["server"],
        "supported_sports": config["supported_sports"],
        "features": config["features"],
        "authentication": auth_manager.get_token_status(),
        "cache_stats": cache_manager.get_cache_stats(),
        "setup_required": not auth_manager.is_configured()
    }


@mcp.tool()
def get_setup_instructions() -> str:
    """
    Get setup instructions for Yahoo Fantasy Sports API access.

    Returns:
        Setup instructions as a string
    """
    auth_manager = app_state["auth_manager"]
    return auth_manager.get_setup_instructions()


@mcp.tool()
def list_available_seasons(sport: str) -> Dict[str, Any]:
    """
    List available seasons for a given sport.

    Args:
        sport: Sport code (nfl, nba, mlb, nhl)

    Returns:
        Available seasons and game IDs for the sport
    """
    if sport.lower() not in config["supported_sports"]:
        return {
            "error": f"Unsupported sport: {sport}",
            "supported_sports": config["supported_sports"]
        }

    sport_data = game_ids.get(sport.lower(), {})
    current_code = game_ids.get("current_codes", {}).get(sport.lower())

    return {
        "sport": sport.lower(),
        "current_season_code": current_code,
        "available_seasons": sport_data,
        "total_seasons": len(sport_data)
    }


@mcp.tool()
def refresh_yahoo_token() -> Dict[str, Any]:
    """
    Refresh the Yahoo API access token.

    Returns:
        Token refresh status and new token information
    """
    auth_manager = app_state["auth_manager"]

    if not auth_manager.is_configured():
        return {
            "status": "error",
            "message": "Yahoo authentication not configured. Check your setup status.",
            "next_step": "Run check_setup_status() to see what needs to be configured"
        }

    # Get current token status
    old_status = auth_manager.get_token_status()

    # Force a token refresh by getting a valid token
    try:
        token_data = auth_manager.get_valid_token()
        new_status = auth_manager.get_token_status()

        if token_data:
            return {
                "status": "success",
                "message": "Token refreshed successfully",
                "old_status": old_status,
                "new_status": new_status
            }
        else:
            return {
                "status": "error",
                "message": "Failed to refresh token. May need to re-authenticate.",
                "current_status": new_status,
                "next_step": "Try reset_authentication() to start fresh, or check_setup_status() for details"
            }
    except Exception as e:
        return {
            "status": "error",
            "message": f"Token refresh failed: {str(e)}",
            "current_status": auth_manager.get_token_status()
        }


@mcp.tool()
def clear_cache(cache_type: str = "all") -> Dict[str, Any]:
    """
    Clear cache data.

    Args:
        cache_type: Type of cache to clear ('all', 'current', 'historical')

    Returns:
        Cache clearing status
    """
    cache_manager = app_state["cache_manager"]

    if cache_type == "all":
        cache_manager.cache.clear()
        return {"status": "success", "message": "All cache cleared"}
    elif cache_type == "current":
        # Clear current season data only
        keys_to_delete = []
        for key in cache_manager.cache._cache.keys():
            if key.startswith("curr_"):
                keys_to_delete.append(key)

        for key in keys_to_delete:
            cache_manager.cache.delete(key)

        return {
            "status": "success",
            "message": f"Cleared {len(keys_to_delete)} current season cache entries"
        }
    else:
        return {"status": "error", "message": "Invalid cache_type. Use 'all', 'current', or 'historical'"}


# =============================================================================
# New Streamlined Authentication Setup Tools
# =============================================================================

@mcp.tool()
def check_setup_status() -> Dict[str, Any]:
    """
    Check the current authentication setup status and provide next steps.

    Returns:
        Current setup state and actionable next steps
    """
    auth_manager = app_state["auth_manager"]

    # Check if consumer credentials exist
    has_credentials = auth_manager.consumer_key and auth_manager.consumer_secret

    # Check if tokens exist
    token_status = auth_manager.get_token_status()
    has_tokens = token_status.get("has_access_token", False)
    is_token_valid = token_status.get("is_valid", False)

    # Determine setup state
    if not has_credentials:
        state = "credentials_needed"
        next_step = "Create a Yahoo Developer app and save credentials using save_yahoo_credentials()"
        message = "Yahoo API credentials not found. You need to create a Yahoo Developer app first."
    elif not has_tokens:
        state = "oauth_needed"
        next_step = "Complete OAuth flow using start_oauth_flow()"
        message = "Credentials found but no access tokens. You need to complete the OAuth authorization."
    elif not is_token_valid:
        state = "token_expired"
        next_step = "Refresh your token using refresh_yahoo_token()"
        message = "Access token has expired and needs to be refreshed."
    else:
        state = "complete"
        next_step = "You're all set! Try using get_league_info() or other fantasy tools."
        message = "Authentication is fully configured and working."

    return {
        "setup_state": state,
        "message": message,
        "next_step": next_step,
        "details": {
            "has_credentials": has_credentials,
            "has_tokens": has_tokens,
            "is_token_valid": is_token_valid,
            "token_status": token_status
        }
    }


@mcp.tool()
def create_yahoo_app() -> Dict[str, Any]:
    """
    Provide step-by-step instructions for creating a Yahoo Developer application.

    Returns:
        Instructions for creating Yahoo app with exact values to use
    """
    return {
        "title": "Create Yahoo Fantasy Sports API Application",
        "url": "https://developer.yahoo.com/apps/",
        "steps": [
            "1. Go to https://developer.yahoo.com/apps/",
            "2. Sign in with your Yahoo account (same one you use for fantasy)",
            "3. Click 'Create an App' button",
            "4. Fill out the form with these exact values:",
            "   • Application Name: League Analysis MCP",
            "   • Application Type: Web Application",
            "   • Description: Fantasy Sports Analysis for MCP",
            "   • Home Page URL: http://localhost",
            "   • Redirect URI(s): https://localhost:8080/",
            "5. Click 'Create App'",
            "6. Copy your Consumer Key and Consumer Secret from the app details page",
            "7. Use save_yahoo_credentials() with your keys"
        ],
        "important_notes": [
            "• Use 'https://localhost:8080/' for the redirect URI - this must match exactly for automated OAuth",
            "• Make sure to use the same Yahoo account for the app and your fantasy leagues",
            "• Keep your Consumer Key and Consumer Secret secure"
        ],
        "next_tool": "save_yahoo_credentials(consumer_key, consumer_secret)"
    }


@mcp.tool()
def save_yahoo_credentials(consumer_key: str, consumer_secret: str) -> Dict[str, Any]:
    """
    Save Yahoo API credentials and validate them.

    Args:
        consumer_key: Your Yahoo app's Consumer Key
        consumer_secret: Your Yahoo app's Consumer Secret

    Returns:
        Status of credential saving and next steps
    """
    if not consumer_key or not consumer_secret:
        return {
            "status": "error",
            "message": "Both consumer_key and consumer_secret are required",
            "next_step": "Get your credentials from https://developer.yahoo.com/apps/ and try again"
        }

    if len(consumer_key) < 10 or len(consumer_secret) < 10:
        return {
            "status": "error",
            "message": "Credentials appear too short. Please verify you copied them correctly.",
            "next_step": "Double-check your Consumer Key and Consumer Secret from your Yahoo app"
        }

    try:
        auth_manager = app_state["auth_manager"]

        # Save credentials using the auth manager
        success = auth_manager.save_credentials(consumer_key, consumer_secret)

        if success:
            return {
                "status": "success",
                "message": f"Yahoo credentials saved successfully! Consumer Key: {consumer_key[:10]}...",
                "next_step": "Start OAuth flow using start_oauth_flow()",
                "next_tool": "start_oauth_flow()"
            }
        else:
            return {
                "status": "error",
                "message": "Failed to save credentials. Check file permissions.",
                "next_step": "Verify the server has write access to the .env file"
            }

    except Exception as e:
        return {
            "status": "error",
            "message": f"Error saving credentials: {str(e)}",
            "next_step": "Check the error and try again"
        }







@mcp.tool()
def start_automated_oauth_flow(open_browser: bool = True, timeout: int = 300) -> Dict[str, Any]:
    """
    Start automated OAuth flow with callback server to capture authorization code automatically.

    This creates an HTTPS server on localhost:8080, opens your browser to Yahoo's authorization page,
    and automatically captures the authorization code when Yahoo redirects back.

    Args:
        open_browser: Whether to automatically open the browser (default: True)
        timeout: Timeout in seconds to wait for authorization (default: 300 = 5 minutes)

    Returns:
        Complete OAuth setup status including token exchange results
    """
    auth_manager = app_state["auth_manager"]

    if not auth_manager.consumer_key:
        return {
            "status": "error",
            "message": "Consumer key not found. Save credentials first.",
            "next_step": "Run save_yahoo_credentials() with your app credentials"
        }

    try:
        # Run automated OAuth flow
        result = automated_oauth_flow(
            auth_manager=auth_manager,
            open_browser=open_browser,
            timeout=timeout
        )

        # If successful, also provide next steps
        if result["status"] == "success":
            result["next_steps"] = [
                "Automated OAuth completed! Your tokens are saved and ready to use.",
                "• Test your connection with test_yahoo_connection()",
                "• Try get_league_info(league_id, sport) with your league ID",
                "• All fantasy sports tools are now available"
            ]

        return result

    except Exception as e:
        logger.error(f"Automated OAuth flow failed: {e}")
        return {
            "status": "error",
            "message": f"Automated OAuth flow failed: {str(e)}",
            "fallback": "You can still use the manual OAuth flow with start_oauth_flow()",
            "troubleshooting": [
                "• Make sure your Yahoo app redirect URI is set to: https://localhost:8080/",
                "• Check that no other service is using port 8080",
                "• Try the manual flow: start_oauth_flow() then complete_oauth_flow(code)"
            ]
        }


@mcp.tool()
def reset_authentication() -> Dict[str, Any]:
    """
    Reset all authentication data and start fresh.

    Returns:
        Reset status and next steps
    """
    try:
        auth_manager = app_state["auth_manager"]

        # Clear all authentication data
        success = auth_manager.reset_authentication()

        if success:
            return {
                "status": "success",
                "message": "🔄 Authentication data cleared successfully",
                "next_step": "Run check_setup_status() to start setup from beginning"
            }
        else:
            return {
                "status": "error",
                "message": "Failed to reset authentication data",
                "next_step": "Check file permissions and try again"
            }

    except Exception as e:
        return {
            "status": "error",
            "message": f"Reset failed: {str(e)}",
            "next_step": "Manual cleanup may be required"
        }


# Register tools and resources from other modules
def initialize_server():
    """Initialize the server with tools and resources."""
    logger.info("Initializing League Analysis MCP Server...")

    # Register tools and resources
    register_tools(mcp, app_state)
    register_team_tools(mcp, app_state)
    register_player_tools(mcp, app_state)
    register_game_tools(mcp, app_state)
    register_utility_tools(mcp, app_state)
    register_resources(mcp, app_state)

    # Validate configuration
    auth_manager = app_state["auth_manager"]
    if not auth_manager.is_configured():
        logger.warning("Yahoo authentication not configured. Only public league access available.")
        logger.info("Run 'check_setup_status' tool to begin streamlined setup.")
    else:
        logger.info("Yahoo authentication configured successfully.")

    logger.info(f"Server initialized with {len(config['supported_sports'])} sports supported")
    logger.info(f"Historical analysis: {'enabled' if config['features']['historical_analysis'] else 'disabled'}")


def main():
    """Main entry point for the server."""
    try:
        initialize_server()

        # Start the server
        logger.info("Starting League Analysis MCP Server...")
        mcp.run()

    except Exception as e:
        logger.error(f"Failed to start server: {e}")
        raise


if __name__ == "__main__":
    main()
