"""
MHA Toolbox - Command Line Interface
Handles different modes: ui, library, demo, list, recommend, run, version
"""

import argparse
import os
import json
import sys

# Fix Unicode encoding for Windows console
if sys.platform == 'win32':
    try:
        sys.stdout.reconfigure(encoding='utf-8')
    except AttributeError:
        pass

from mha_toolbox.toolbox import MHAToolbox
from mha_toolbox import __version__


def _load_dataset(name):
    """Load a dataset by name"""
    if name is None:
        return None, None
    name = name.lower()
    if name == 'breast_cancer':
        from sklearn.datasets import load_breast_cancer
        data = load_breast_cancer()
        return data.data, data.target
    if name == 'iris':
        from sklearn.datasets import load_iris
        data = load_iris()
        return data.data, data.target
    raise ValueError(f"Unknown dataset '{name}'")


def main():
    parser = argparse.ArgumentParser(
        prog='mha-flow',
        description='MHA Flow v' + __version__ + ' - Meta-Heuristic Algorithms for Optimization',
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
Commands:
  ui          Launch Flask web interface (http://127.0.0.1:5000)
  demo        Run interactive demo
  list        List all 142+ available algorithms
  recommend   Get AI-powered algorithm recommendations
  run         Run specific algorithm on dataset
  info        Show algorithm information
  version     Show version information

Examples:
  mha-flow ui                           # Launch web interface
  mha-flow ui --port 8080               # Custom port
  mha-flow list                         # Show all algorithms
  mha-flow list --category swarm        # Filter by category
  mha-flow recommend --interactive      # Get recommendations
  mha-flow run pso --dataset breast_cancer
  mha-flow info gwo
  
For library usage:
  from mha_toolbox import optimize
  result = optimize('pso', X, y)

Documentation: https://github.com/Achyut103040/MHA-Algorithm
        """
    )
    
    # Add version argument
    parser.add_argument('--version', '-v', action='version', 
                        version=f'MHA Flow v{__version__}')
    
    sub = parser.add_subparsers(dest='command')

    # version command
    ver_p = sub.add_parser('version', help='Show version information')

    # ui - Web Interface
    ui_p = sub.add_parser('ui', help='Launch Flask web interface')
    ui_p.add_argument('--port', type=int, default=5000, help='Port number (default: 5000)')
    ui_p.add_argument('--host', default='127.0.0.1', help='Host address (default: 127.0.0.1)')
    ui_p.add_argument('--debug', action='store_true', help='Run in debug mode')

    # demo - Interactive Demo
    demo_p = sub.add_parser('demo', help='Run interactive demo')

    # list - Show all algorithms
    list_p = sub.add_parser('list', help='List available algorithms')
    list_p.add_argument('--category', help='Filter by category (swarm, evolution, hybrid)')

    # recommend - Algorithm recommender
    rec_p = sub.add_parser('recommend', help='Get algorithm recommendations')
    rec_p.add_argument('--interactive', action='store_true', help='Interactive mode')

    # info - Algorithm information
    info_p = sub.add_parser('info', help='Show info for an algorithm')
    info_p.add_argument('algorithm', help='Algorithm name')

    # run - Execute algorithm
    run_p = sub.add_parser('run', help='Run an algorithm')
    run_p.add_argument('algorithm', help='Algorithm name')
    run_p.add_argument('--dataset', default=None, help='Dataset name (e.g. breast_cancer, iris)')
    run_p.add_argument('--population_size', type=int, default=None)
    run_p.add_argument('--max_iterations', type=int, default=None)
    run_p.add_argument('--dimensions', type=int, default=None)
    run_p.add_argument('--output', default='results', help='Output folder')
    run_p.add_argument('--save_model', action='store_true', help='Also pickle the model')

    args = parser.parse_args()
    toolbox = MHAToolbox()
    
    # Handle version command
    if args.command == 'version':
        print(f"\n🚀 MHA Flow v{__version__}")
        print("="*50)
        print("Professional Meta-Heuristic Algorithm Library")
        print("="*50)
        print(f"  📦 Version:    {__version__}")
        print(f"  🐍 Python:     {sys.version.split()[0]}")
        print(f"  📁 Location:   {os.path.dirname(os.path.abspath(__file__))}")
        print(f"  🌐 Repository: https://github.com/Achyut103040/MHA-Algorithm")
        print(f"  📖 License:    MIT")
        print("="*50)
        return
    
    if not args.command:
        parser.print_help()
        print("\n" + "="*70)
        print("🚀 Quick Start Guide:")
        print("="*70)
        print("\n1️⃣  Flask Web Interface (Recommended for All Users):")
        print("   python -m mha_toolbox ui")
        print("   → Full-featured web interface with:")
        print("      • User authentication & history tracking")
        print("      • Visual algorithm selection & comparison")
        print("      • Dataset upload & preprocessing")
        print("      • Real-time optimization tracking")
        print("      • Custom algorithm submission (via GitHub)")
        print("\n2️⃣  Library Mode (For Python Developers):")
        print("   from mha_toolbox import optimize")
        print("   result = optimize('pso', X_train, y_train)")
        print("   → Direct Python API for integration into your code")
        print("\n3️⃣  Algorithm Recommender:")
        print("   python -m mha_toolbox recommend --interactive")
        print("   → Get personalized algorithm suggestions")
        print("\n" + "="*70)
        return

    if args.command == 'ui':
        print("\n" + "="*70)
        print("🌐 Starting MHA Flow Production Server...")
        print(f"📊 Access the web interface at: http://{args.host}:{args.port}")
        print("\n✨ Features:")
        print("   • 🔐 User authentication & secure login")
        print("   • 📊 Personal optimization history")
        print("   • 🤖 142+ meta-heuristic algorithms")
        print("   • 📈 Real-time progress tracking")
        print("   • 📊 Advanced visualizations")
        print("   • 🔧 Custom algorithm submission (GitHub PR workflow)")
        print("   • ☁️  Cloud database support (MongoDB Atlas)")
        print("\n💡 Press Ctrl+C to stop the server")
        print("="*70 + "\n")
        
        try:
            # Import and run Flask production app
            from pathlib import Path
            
            # Add parent directory to path to import app_production
            parent_dir = str(Path(__file__).parent.parent)
            if parent_dir not in sys.path:
                sys.path.insert(0, parent_dir)
            
            from app_production import app, db
            
            # Create database tables if they don't exist
            with app.app_context():
                db.create_all()
                print("✅ Database initialized successfully\n")
            
            # Run the Flask app
            app.run(
                host=args.host,
                port=args.port,
                debug=args.debug
            )
            
        except ImportError as e:
            print(f"\n❌ Error: {e}")
            print("\n📦 Flask dependencies not installed. Install with:")
            print("   pip install -r requirements.txt")
            sys.exit(1)
        except Exception as e:
            print(f"\n❌ Error starting server: {e}")
            sys.exit(1)
        return

    if args.command == 'demo':
        print("🎮 Starting Interactive Demo...")
        try:
            from mha_toolbox.demo_system import run_demo_system
            run_demo_system()
        except ImportError:
            print("Running basic demo...")
            # Basic demo
            from mha_toolbox import optimize
            print("\n📊 Running PSO on Sphere function...")
            result = optimize('pso', dimensions=10, max_iterations=50)
            print(f"✅ Best fitness: {result.best_fitness}")
        return

    if args.command == 'list':
        names = toolbox.get_all_algorithm_names()
        
        if args.category:
            category = args.category.lower()
            if category == 'hybrid':
                names = [n for n in names if 'hybrid' in n.lower() or '_' in n]
            elif category == 'swarm':
                names = [n for n in names if any(k in n.lower() for k in ['pso', 'gwo', 'woa', 'alo', 'mvo', 'sca', 'ssa', 'abc'])]
            elif category == 'evolution':
                names = [n for n in names if any(k in n.lower() for k in ['ga', 'de', 'es', 'ep'])]
        
        print(f"\n📋 Available Algorithms ({len(names)} total):\n")
        print("="*50)
        
        # Group by first letter for readability
        from collections import defaultdict
        grouped = defaultdict(list)
        for name in sorted(names):
            grouped[name[0].upper()].append(name)
        
        for letter in sorted(grouped.keys()):
            print(f"\n{letter}:")
            for alg in grouped[letter]:
                print(f"  • {alg}")
        
        print("\n" + "="*50)
        print(f"Total: {len(names)} algorithms")
        print("="*50)
        return

    if args.command == 'recommend':
        print("\n🎯 Algorithm Recommendation System")
        print("="*70)
        
        if args.interactive:
            print("\n📊 Please provide your dataset characteristics:\n")
            
            try:
                dataset_size = input("  1. Dataset size (small/medium/large): ").lower().strip()
                problem_type = input("  2. Problem type (classification/regression/function): ").lower().strip()
                features = input("  3. Number of features: ").strip()
                samples = input("  4. Number of samples: ").strip()
                
                from mha_toolbox.algorithm_recommender import AlgorithmRecommender
                recommender = AlgorithmRecommender()
                
                characteristics = {
                    'n_samples': int(samples) if samples.isdigit() else 1000,
                    'n_features': int(features) if features.isdigit() else 10,
                    'problem_type': problem_type,
                    'dataset_size': dataset_size
                }
                
                recommendations = recommender.recommend(characteristics)
                
                print("\n✨ Top 5 Recommended Algorithms:\n")
                print("="*70)
                for i, rec in enumerate(recommendations[:5], 1):
                    algo_name = rec.get('algorithm', rec.get('name', 'Unknown'))
                    score = rec.get('score', rec.get('confidence', 0.8))
                    reason = rec.get('reason', 'Suitable for your problem characteristics')
                    
                    print(f"\n{i}. {algo_name.upper()}")
                    print(f"   📊 Confidence Score: {score:.2%}")
                    print(f"   💡 Reason: {reason}")
                
                print("\n" + "="*70)
                print("\n💡 Tip: You can try multiple algorithms and compare results!")
                
            except KeyboardInterrupt:
                print("\n\n👋 Cancelled")
                sys.exit(0)
            except Exception as e:
                print(f"\n❌ Error: {e}")
                sys.exit(1)
        else:
            print("\nUse --interactive flag for interactive mode")
            print("Example: python -m mha_toolbox recommend --interactive")
        
        return

    if args.command == 'info':
        info = toolbox.get_algorithm_info(args.algorithm)
        print(f"\n📖 Algorithm Information: {args.algorithm.upper()}")
        print("="*70)
        print(json.dumps(info, indent=2, default=str))
        return

    if args.command == 'run':
        X, y = _load_dataset(args.dataset)
        params = {}
        if args.population_size is not None:
            params['population_size'] = args.population_size
        if args.max_iterations is not None:
            params['max_iterations'] = args.max_iterations
        if args.dimensions is not None:
            params['dimensions'] = args.dimensions

        print(f"\n🚀 Running {args.algorithm.upper()}")
        print("="*70)
        print(f"Dataset: {args.dataset or 'custom/synthetic'}")
        print(f"Parameters: {params}")
        print("="*70 + "\n")
        
        result = toolbox.optimize(args.algorithm, X=X, y=y, **params)

        # Ensure output dir exists
        outdir = args.output
        os.makedirs(outdir, exist_ok=True)
        base = os.path.join(outdir, f"{args.algorithm}_{args.dataset or 'run'}")
        primary = result.save(base + '.json')
        if args.save_model:
            result.save_model(base + '_model.pkl')

        print(f"\n✅ Results saved to: {primary}")
        print(f"📊 Best fitness: {result.best_fitness}")
        if hasattr(result, 'selected_features') and result.selected_features is not None:
            print(f"🎯 Selected features: {len(result.selected_features)}")
        return

    parser.print_help()


if __name__ == '__main__':
    main()

