"""
Initialization function for the CCS library.

The init() function must be called before using any other CCS functionality.
It configures the backend URLs, authentication, and application settings.
"""

import random
from typing import Optional, Dict, Any

from ccs.config.base_url import BaseUrl
from ccs.config.token_storage import TokenStorage
from ccs.data.local_id import LocalId


# Module-level state
_initialized: bool = False


async def init(
    url: str = "",
    aiUrl: str = "",
    accessToken: str = "",
    nodeUrl: str = "",
    enableAi: bool = True,
    applicationName: str = "",
    flags: Optional[Dict[str, bool]] = None,
    parameters: Optional[Dict[str, str]] = None,
) -> bool:
    """
    Initialize the CCS library with backend configuration.

    This function MUST be called before using any other CCS functionality.
    It sets up the backend URLs, authentication tokens, and application settings.

    Args:
        url: The base URL for the CCS backend API.
             Example: "https://api.freeschema.com"

        aiUrl: The URL for the AI service.
               Example: "https://ai.freeschema.com"

        accessToken: JWT bearer token for authentication.
                    Can be empty initially and set later with updateAccessToken().

        nodeUrl: URL for the Node.js server (used for local sync, ghost IDs, etc.)
                Example: "http://localhost:5001"

        enableAi: Whether to enable AI features. Defaults to True.

        applicationName: Name identifier for this application.
                        Used for logging and tracking.

        flags: Optional dictionary of feature flags:
              - logApplication: Enable application-level logging (default: False)
              - logPackage: Enable package-level logging (default: False)
              - accessTracker: Enable access tracking (default: False)
              - isTest: Mark as test environment (default: False)

        parameters: Optional dictionary of additional parameters:
                   - logserver: URL for the log server

    Returns:
        True if initialization was successful.

    Example:
        >>> import asyncio
        >>> from ccs import init
        >>>
        >>> async def main():
        ...     await init(
        ...         url="https://api.freeschema.com",
        ...         aiUrl="https://ai.freeschema.com",
        ...         accessToken="your-jwt-token",
        ...         nodeUrl="http://localhost:5001",
        ...         applicationName="MyApp",
        ...         flags={"logApplication": True}
        ...     )
        ...     print("CCS initialized!")
        >>>
        >>> asyncio.run(main())

    Example:
        >>> # Minimal initialization (local-only mode)
        >>> await init(url="https://api.example.com")

    Example:
        >>> # Initialize without token, add later
        >>> await init(url="https://api.example.com")
        >>> # ... user logs in ...
        >>> updateAccessToken("user-jwt-token")
    """
    global _initialized

    try:
        # Set base URLs
        BaseUrl.BASE_URL = url if url else BaseUrl.BASE_URL
        BaseUrl.AI_URL = aiUrl if aiUrl else BaseUrl.AI_URL
        BaseUrl.NODE_URL = nodeUrl if nodeUrl else BaseUrl.NODE_URL
        BaseUrl.BASE_APPLICATION = applicationName

        # Set log server from parameters
        if parameters and parameters.get("logserver"):
            BaseUrl.LOG_SERVER = parameters["logserver"]

        # Update access token
        updateAccessToken(accessToken)

        # Generate randomizer for this session
        randomizer = random.randint(1, 100_000_000)
        BaseUrl.setRandomizer(randomizer)

        # Reset local ID counters for new session
        LocalId.reset()

        # Set default flags
        defaultFlags = {
            "logApplication": False,
            "logPackage": False,
            "accessTracker": False,
            "isTest": False
        }
        BaseUrl.FLAGS = defaultFlags

        # Merge provided flags with defaults
        if flags:
            BaseUrl.FLAGS = {**defaultFlags, **flags}

        _initialized = True

        return True

    except Exception as error:
        print(f"Cannot initialize the CCS system: {error}")
        raise error


def updateAccessToken(accessToken: str) -> None:
    """
    Update the bearer access token for API authentication.

    Call this function after user login to set the JWT token,
    or when the token needs to be refreshed.

    Args:
        accessToken: The JWT bearer token for authentication.

    Example:
        >>> from ccs import updateAccessToken
        >>> updateAccessToken("new-jwt-token-after-login")
    """
    TokenStorage.setToken(accessToken)


def isInitialized() -> bool:
    """
    Check if the CCS library has been initialized.

    Returns:
        True if init() has been called successfully.
    """
    return _initialized


def getConfig() -> Dict[str, Any]:
    """
    Get the current configuration.

    Returns:
        Dictionary with current configuration values.
    """
    return {
        "baseUrl": BaseUrl.BASE_URL,
        "aiUrl": BaseUrl.AI_URL,
        "nodeUrl": BaseUrl.NODE_URL,
        "applicationName": BaseUrl.BASE_APPLICATION,
        "logServer": BaseUrl.LOG_SERVER,
        "flags": BaseUrl.FLAGS,
        "randomizer": BaseUrl.BASE_RANDOMIZER,
        "isAuthenticated": TokenStorage.isAuthenticated(),
    }
