#!/usr/bin/env python3
"""
Claude-style Code CLI for MiniMax Client

A powerful command-line interface for code analysis, generation, and interactive
programming assistance using the MiniMax AI model.
"""

import argparse
import sys
import os
from typing import List, Optional, Dict, Any
import logging

from .config import Configuration
from .client import initialize_client
from .environment import check_environment


class CodeCLI:
    """Main CLI class for the MiniMax Code assistant."""
    
    def __init__(self):
        self.config = None
        self.client = None
        self.logger = logging.getLogger(__name__)
        
    def setup(self):
        """Initialize the CLI with configuration and client."""
        try:
            # Load configuration
            self.config = Configuration()
            
            # Check environment and get token
            api_key = check_environment()
            
            # Initialize client
            self.client = initialize_client(api_key, self.config)
            
            self.logger.info("✓ MiniMax Code CLI initialized successfully")
            return True
            
        except Exception as e:
            self.logger.error(f"Failed to initialize CLI: {e}")
            return False
    
    def create_parser(self) -> argparse.ArgumentParser:
        """Create the main argument parser with subcommands."""
        parser = argparse.ArgumentParser(
            prog='minimax-code',
            description='Claude-style Code CLI powered by MiniMax AI',
            formatter_class=argparse.RawDescriptionHelpFormatter,
            epilog="""
Examples:
  minimax-code analyze review myfile.py
  minimax-code generate function "calculate fibonacci" --language python
  minimax-code chat start
  minimax-code edit modify app.py "add error handling"
  minimax-code project scan
            """
        )
        
        # Global options
        parser.add_argument(
            '--verbose', '-v',
            action='store_true',
            help='Enable verbose output'
        )
        
        parser.add_argument(
            '--model',
            type=str,
            help='Override default model'
        )
        
        parser.add_argument(
            '--ui',
            type=str,
            choices=['console', 'rich', 'tui', 'widgets'],
            default='console',
            help='UI mode: console (default), rich (enhanced colors/formatting), tui (full terminal UI), or widgets (advanced display)'
        )
        
        # Create subparsers
        subparsers = parser.add_subparsers(
            dest='command',
            help='Available commands',
            metavar='COMMAND'
        )
        
        # Add subcommands
        self._add_analyze_commands(subparsers)
        self._add_generate_commands(subparsers)
        self._add_edit_commands(subparsers)
        self._add_chat_commands(subparsers)
        self._add_project_commands(subparsers)
        
        return parser
    
    def _add_analyze_commands(self, subparsers):
        """Add analyze subcommands."""
        analyze_parser = subparsers.add_parser(
            'analyze',
            help='Analyze code files and projects'
        )
        
        analyze_subparsers = analyze_parser.add_subparsers(
            dest='analyze_action',
            help='Analysis actions'
        )
        
        # Review command
        review_parser = analyze_subparsers.add_parser(
            'review',
            help='Review code for issues and improvements'
        )
        review_parser.add_argument('files', nargs='+', help='Files to review')
        review_parser.add_argument('--focus', choices=['security', 'performance', 'style', 'bugs'], 
                                 help='Focus area for review')
        
        # Explain command
        explain_parser = analyze_subparsers.add_parser(
            'explain',
            help='Explain how code works'
        )
        explain_parser.add_argument('file', help='File to explain')
        explain_parser.add_argument('--function', help='Specific function to explain')
        explain_parser.add_argument('--lines', help='Line range (e.g., 10-20)')
        
        # Debug command
        debug_parser = analyze_subparsers.add_parser(
            'debug',
            help='Help debug code issues'
        )
        debug_parser.add_argument('file', help='File with issues')
        debug_parser.add_argument('--error', help='Error message or description')
        debug_parser.add_argument('--context', help='Additional context')
        
        # Optimize command
        optimize_parser = analyze_subparsers.add_parser(
            'optimize',
            help='Suggest code optimizations'
        )
        optimize_parser.add_argument('file', help='File to optimize')
        optimize_parser.add_argument('--target', choices=['speed', 'memory', 'readability'], 
                                   help='Optimization target')
    
    def _add_generate_commands(self, subparsers):
        """Add generate subcommands."""
        generate_parser = subparsers.add_parser(
            'generate',
            help='Generate new code'
        )
        
        generate_subparsers = generate_parser.add_subparsers(
            dest='generate_action',
            help='Generation actions'
        )
        
        # Function command
        function_parser = generate_subparsers.add_parser(
            'function',
            help='Generate a function'
        )
        function_parser.add_argument('description', help='Function description')
        function_parser.add_argument('--language', '-l', default='python', help='Programming language')
        function_parser.add_argument('--output', '-o', help='Output file')
        function_parser.add_argument('--tests', action='store_true', help='Generate tests too')
        
        # Class command
        class_parser = generate_subparsers.add_parser(
            'class',
            help='Generate a class'
        )
        class_parser.add_argument('description', help='Class description')
        class_parser.add_argument('--language', '-l', default='python', help='Programming language')
        class_parser.add_argument('--output', '-o', help='Output file')
        
        # Test command
        test_parser = generate_subparsers.add_parser(
            'test',
            help='Generate tests for existing code'
        )
        test_parser.add_argument('file', help='File to generate tests for')
        test_parser.add_argument('--framework', help='Test framework to use')
        test_parser.add_argument('--output', '-o', help='Output test file')
        
        # Project command
        project_parser = generate_subparsers.add_parser(
            'project',
            help='Scaffold a new project'
        )
        project_parser.add_argument('name', help='Project name')
        project_parser.add_argument('--type', choices=['web', 'api', 'cli', 'library'], 
                                  help='Project type')
        project_parser.add_argument('--language', '-l', default='python', help='Programming language')
    
    def _add_edit_commands(self, subparsers):
        """Add edit subcommands."""
        edit_parser = subparsers.add_parser(
            'edit',
            help='Edit and modify existing files'
        )
        
        edit_subparsers = edit_parser.add_subparsers(
            dest='edit_action',
            help='Edit actions'
        )
        
        # Modify command
        modify_parser = edit_subparsers.add_parser(
            'modify',
            help='Modify existing code'
        )
        modify_parser.add_argument('file', help='File to modify')
        modify_parser.add_argument('instruction', help='Modification instruction')
        modify_parser.add_argument('--backup', action='store_true', help='Create backup')
        modify_parser.add_argument('--preview', action='store_true', help='Preview changes only')
        
        # Refactor command
        refactor_parser = edit_subparsers.add_parser(
            'refactor',
            help='Refactor code structure'
        )
        refactor_parser.add_argument('file', help='File to refactor')
        refactor_parser.add_argument('--type', choices=['extract', 'inline', 'rename', 'move'], 
                                   help='Refactoring type')
        refactor_parser.add_argument('--target', help='Target element to refactor')
        
        # Format command
        format_parser = edit_subparsers.add_parser(
            'format',
            help='Format and style code'
        )
        format_parser.add_argument('files', nargs='+', help='Files to format')
        format_parser.add_argument('--style', help='Code style guide')
    
    def _add_chat_commands(self, subparsers):
        """Add chat subcommands."""
        chat_parser = subparsers.add_parser(
            'chat',
            help='Interactive coding assistance'
        )
        
        chat_subparsers = chat_parser.add_subparsers(
            dest='chat_action',
            help='Chat actions'
        )
        
        # Start command
        start_parser = chat_subparsers.add_parser(
            'start',
            help='Start interactive session'
        )
        start_parser.add_argument('--context', help='Initial context or file')
        start_parser.add_argument('--project', help='Project directory for context')
        
        # Context command
        context_parser = chat_subparsers.add_parser(
            'context',
            help='Manage conversation context'
        )
        context_parser.add_argument('action', choices=['add', 'remove', 'list', 'clear'])
        context_parser.add_argument('--file', help='File to add/remove from context')
    
    def _add_project_commands(self, subparsers):
        """Add project subcommands."""
        project_parser = subparsers.add_parser(
            'project',
            help='Project-level operations'
        )
        
        project_subparsers = project_parser.add_subparsers(
            dest='project_action',
            help='Project actions'
        )
        
        # Init command
        init_parser = project_subparsers.add_parser(
            'init',
            help='Initialize project for MiniMax Code'
        )
        init_parser.add_argument('--directory', '-d', default='.', help='Project directory')
        
        # Scan command
        scan_parser = project_subparsers.add_parser(
            'scan',
            help='Scan project structure'
        )
        scan_parser.add_argument('--directory', '-d', default='.', help='Project directory')
        scan_parser.add_argument('--depth', type=int, default=3, help='Scan depth')
        
        # Summary command
        summary_parser = project_subparsers.add_parser(
            'summary',
            help='Generate project summary'
        )
        summary_parser.add_argument('--directory', '-d', default='.', help='Project directory')
        summary_parser.add_argument('--include-files', action='store_true', help='Include file contents')


def main():
    """Main entry point for the CLI."""
    cli = CodeCLI()
    
    # Setup logging
    logging.basicConfig(
        level=logging.INFO,
        format='%(levelname)s - %(message)s'
    )
    
    # Initialize CLI
    if not cli.setup():
        print("❌ Failed to initialize MiniMax Code CLI", file=sys.stderr)
        print("Please check your configuration and API key.", file=sys.stderr)
        sys.exit(1)
    
    # Parse arguments
    parser = cli.create_parser()
    args = parser.parse_args()
    
    # Handle verbose mode
    if args.verbose:
        logging.getLogger().setLevel(logging.DEBUG)
        cli.logger.debug("Verbose mode enabled")
        cli.logger.debug(f"UI mode: {args.ui}")
        if args.model:
            cli.logger.debug(f"Model override: {args.model}")
    
    # Initialize theme system
    try:
        from .ui.theme import load_theme_config, set_theme
        load_theme_config()
        
        # Set theme from environment or args if available
        theme_override = os.environ.get('MINIMAX_THEME')
        if theme_override:
            set_theme(theme_override)
    except ImportError:
        # Theme system not available, continue without it
        pass
    except Exception as e:
        cli.logger.debug(f"Failed to initialize theme system: {e}")
    
    # Create presenter based on UI mode with enhanced configuration
    try:
        from .presentation.factory import create_presenter, validate_presenter_config
        
        # Prepare presenter configuration
        presenter_config = {
            'use_emojis': True,
            'verbose': args.verbose
        }
        
        # Add UI-specific configuration
        if args.ui == 'rich':
            presenter_config.update({
                'use_colors': True,
                'color_system': 'auto'
            })
        elif args.ui == 'tui':
            presenter_config.update({
                'app_title': 'MiniMax Code CLI',
                'theme': 'dark'
            })
        
        # Validate and create presenter
        validated_config = validate_presenter_config(args.ui, presenter_config)
        presenter = create_presenter(args.ui, **validated_config)
        
    except ImportError as e:
        # Fallback if presentation layer is not available
        print(f"⚠️  Presentation layer not available: {e}", file=sys.stderr)
        print("Using basic console output.", file=sys.stderr)
        presenter = None
    except Exception as e:
        print(f"⚠️  Failed to create presenter: {e}", file=sys.stderr)
        print("Using basic console output.", file=sys.stderr)
        presenter = None
    
    # Handle TUI mode specially
    if args.ui == 'tui' and presenter is not None:
        try:
            from .ui.app import MiniMaxApp
            
            # Create and run the Textual application
            app = MiniMaxApp(
                client=cli.client,
                config=cli.config,
                args=args
            )
            
            # Run the TUI application
            app.run()
            sys.exit(0)
            
        except ImportError:
            if presenter:
                presenter.show_error(
                    "Textual UI is not available. Install with: pip install minimax-client[ui]"
                )
                presenter.show_info("Falling back to rich/console mode...")
            else:
                print("⚠️  Textual UI is not available. Install with: pip install minimax-client[ui]", file=sys.stderr)
                print("Falling back to console mode...", file=sys.stderr)
            # Continue with normal flow using the fallback presenter
        except Exception as e:
            if presenter:
                presenter.show_error(f"Failed to launch TUI: {e}")
                presenter.show_info("Falling back to rich/console mode...")
            else:
                print(f"⚠️  Failed to launch TUI: {e}", file=sys.stderr)
                print("Falling back to console mode...", file=sys.stderr)
            # Continue with normal flow
    
    # Route to appropriate handler
    if not args.command:
        if presenter:
            presenter.show_info("No command specified. Use --help for available commands.")
        parser.print_help()
        sys.exit(1)
    
    try:
        # Import and use command handlers with proper presenter integration
        from .commands.router import CommandRouter
        
        # Ensure presenter is available for command routing
        if presenter is None:
            # Create a minimal console presenter as absolute fallback
            try:
                from .presentation.console import ConsolePresenter
                presenter = ConsolePresenter()
            except ImportError:
                # If even console presenter fails, we have a serious problem
                cli.logger.error("Critical error: No presenter available")
                sys.exit(1)
        
        # Create router with presenter integration
        router = CommandRouter(cli.client, cli.config, presenter)
        result = router.route(args)
        
        if result:
            if presenter:
                presenter.show_success("Operation completed successfully")
            sys.exit(0)
        else:
            if presenter:
                presenter.show_error("Operation failed")
            sys.exit(1)
            
    except KeyboardInterrupt:
        if presenter:
            presenter.show_warning("\nOperation cancelled by user")
        else:
            print("\n⚠️  Operation cancelled by user", file=sys.stderr)
        sys.exit(130)
    except Exception as e:
        error_msg = f"Unexpected error: {e}"
        if presenter:
            presenter.show_error(error_msg)
            if args.verbose:
                # Use presenter for debug info if available
                import traceback
                presenter.show_info("Debug traceback:")
                presenter.show_code(traceback.format_exc(), language="text")
        else:
            cli.logger.error(error_msg)
            if args.verbose:
                import traceback
                traceback.print_exc()
        sys.exit(1)


if __name__ == '__main__':
    main()
