#!/usr/bin/env python3
"""
Main orchestration module for MiniMax client.

This module coordinates all components and serves as the entry point for the CLI command.
It handles configuration, environment validation, client initialization, and chat completion.
"""

import logging
import sys
from typing import Optional

from .config import Configuration
from .environment import check_environment
from .client import initialize_client
from .chat import create_chat_completion, validate_chat_parameters
from .exceptions import (
    MiniMaxClientError,
    ConfigurationError,
    AuthenticationError,
    NetworkError,
    ModelError,
    APIError,
    RetryableError
)


def setup_logging(log_level: str = "INFO") -> None:
    """
    Configure logging for the application.
    
    Args:
        log_level: Logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
    """
    # Convert string to logging level
    numeric_level = getattr(logging, log_level.upper(), logging.INFO)
    
    # Configure logging format
    log_format = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
    
    # Configure root logger
    logging.basicConfig(
        level=numeric_level,
        format=log_format,
        datefmt="%Y-%m-%d %H:%M:%S"
    )
    
    # Set specific logger levels
    logger = logging.getLogger(__name__)
    logger.setLevel(numeric_level)
    
    # Reduce noise from external libraries
    logging.getLogger("urllib3").setLevel(logging.WARNING)
    logging.getLogger("requests").setLevel(logging.WARNING)


def main() -> None:
    """
    Main function to orchestrate the MiniMax client operations.

    This function coordinates all components:
    1. Configuration loading and validation
    2. Logging setup
    3. Environment validation
    4. Client initialization
    5. Chat completion execution

    Exit codes:
        0: Success
        1: General error
        2: Configuration error
        3: Network error
        4: Authentication error
        5: Model error
    """
    # Initialize basic logging first
    setup_logging()
    logger = logging.getLogger(__name__)
    
    try:
        logger.info("🤖 MiniMax-M1-80k Client")
        logger.info("=" * 40)
        
        # Step 1: Load and validate configuration
        logger.info("1. Loading configuration...")
        try:
            config = Configuration()
            logger.info("✓ Configuration loaded successfully")
            logger.debug("Configuration details:")
            for key, value in config.get_config_dict().items():
                if key == 'hf_token':
                    logger.debug(f"  {key}: {'***' if value else 'Not set'}")
                else:
                    logger.debug(f"  {key}: {value}")
        except SystemExit:
            # Configuration validation failed, exit code already set
            raise
        except Exception as e:
            logger.error(f"Failed to load configuration: {e}")
            sys.exit(2)
        
        # Step 2: Setup logging with configured level
        # Note: In a more advanced setup, log level could be configurable
        setup_logging("INFO")
        
        # Step 3: Validate environment
        logger.info("2. Checking environment...")
        try:
            api_key = check_environment()
            logger.info("✓ Environment validation completed")
        except SystemExit:
            # Environment check failed, exit code already set
            raise
        except Exception as e:
            logger.error(f"Environment validation failed: {e}")
            sys.exit(2)
        
        # Step 4: Validate chat parameters
        logger.info("3. Validating parameters...")
        try:
            validate_chat_parameters(
                model_name=config.model_name,
                user_message=config.user_message
            )
            logger.info("✓ Parameters validated successfully")
        except ValueError as e:
            logger.error(f"Parameter validation failed: {e}")
            sys.exit(2)
        except Exception as e:
            logger.error(f"Unexpected error during parameter validation: {e}")
            sys.exit(1)
        
        # Step 5: Initialize the InferenceClient
        logger.info("4. Initializing client...")
        try:
            client = initialize_client(api_key, config)
            logger.info("✓ Client initialization completed")
        except SystemExit:
            # Client initialization failed, exit code already set
            raise
        except Exception as e:
            logger.error(f"Client initialization failed: {e}")
            sys.exit(1)
        
        # Step 6: Create and process chat completion
        logger.info("5. Creating chat completion...")
        try:
            response = create_chat_completion(
                client=client,
                model_name=config.model_name,
                user_message=config.user_message,
                stream=config.streaming
            )
            
            if response:
                logger.info("✓ Chat completion successful")
                logger.debug(f"Response length: {len(response)} characters")
            else:
                logger.warning("Chat completion returned empty response")
                
        except AuthenticationError as e:
            logger.error(f"Authentication failed: {e}")
            sys.exit(4)
        except ModelError as e:
            logger.error(f"Model error: {e}")
            sys.exit(5)
        except NetworkError as e:
            logger.error(f"Network error: {e}")
            sys.exit(3)
        except APIError as e:
            logger.error(f"API error: {e}")
            sys.exit(5)
        except RetryableError as e:
            logger.error(f"Service temporarily unavailable: {e}")
            logger.info("Please try again later")
            sys.exit(3)
        except MiniMaxClientError as e:
            logger.error(f"MiniMax client error: {e}")
            if e.error_code:
                logger.debug(f"Error code: {e.error_code}")
            if e.details:
                logger.debug(f"Error details: {e.details}")
            sys.exit(5)
        except Exception as e:
            logger.error(f"Unexpected error during chat completion: {e}")
            sys.exit(1)
        
        # Success
        logger.info("🎉 Client operation completed successfully!")

    except KeyboardInterrupt:
        logger.info("Client operation interrupted by user")
        sys.exit(130)  # Standard exit code for SIGINT
        
    except SystemExit:
        # Re-raise SystemExit to preserve exit codes
        raise
        
    except Exception as e:
        logger.error(f"Unexpected error in main: {e}")
        logger.debug("Exception details:", exc_info=True)
        sys.exit(1)


def cli_main() -> None:
    """
    CLI entry point that can be used by console scripts.
    
    This function provides a clean entry point for setuptools console scripts
    and handles any final exception catching.
    """
    try:
        main()
    except Exception as e:
        # Final safety net for any uncaught exceptions
        print(f"Fatal error: {e}", file=sys.stderr)
        sys.exit(1)


if __name__ == "__main__":
    cli_main()