#!/usr/bin/env python3
"""
llmass - AI-powered email management and automation system
Komendy:
  llmass generate - Generuj testowe emaile (email_generator)
  llmass clean    - Organizuj i kategoryzuj emaile (email_organizer)
  llmass write    - Generuj odpowiedzi z AI (email_responder)
  llmass test     - Uruchom testy
"""

__version__ = "1.1.22"

import sys
import argparse
from typing import List
import os
import subprocess
from dotenv import load_dotenv


def check_and_install_dependencies(packages: List[str], install_browsers: bool = False, auto_install: bool = True) -> bool:
    """
    Sprawdza i instaluje brakujące zależności.
    
    Args:
        packages: Lista pakietów do sprawdzenia
        install_browsers: Czy zainstalować przeglądarki Playwright
        auto_install: Czy automatycznie instalować (domyślnie: True)
    
    Returns:
        True jeśli wszystko OK, False jeśli błąd
    """
    missing_packages = []
    
    for package in packages:
        try:
            __import__(package.replace('-', '_'))
        except ImportError:
            missing_packages.append(package)
    
    if not missing_packages and not install_browsers:
        return True
    
    if missing_packages:
        if not auto_install:
            print(f"❌ Brakujące zależności: {', '.join(missing_packages)}")
            print(f"💡 Zainstaluj: pip install {' '.join(missing_packages)}")
            return False
        
        print(f"\n📦 Wykryto brakujące zależności: {', '.join(missing_packages)}")
        print("🔄 Rozpoczynam automatyczną instalację...\n")
        
        try:
            # Install missing packages
            cmd = [sys.executable, '-m', 'pip', 'install'] + missing_packages
            result = subprocess.run(cmd, check=True, capture_output=True, text=True)
            print(f"✅ Zainstalowano: {', '.join(missing_packages)}")
        except subprocess.CalledProcessError as e:
            print(f"❌ Błąd instalacji: {e}")
            print(f"💡 Spróbuj ręcznie: pip install {' '.join(missing_packages)}")
            return False
    
    # Install Playwright browsers if needed
    if install_browsers:
        try:
            import playwright
            from pathlib import Path
            
            # Check if browser executable exists
            # Playwright stores browsers in ~/.cache/ms-playwright or similar
            browser_installed = False
            home = Path.home()
            possible_paths = [
                home / '.cache' / 'ms-playwright',
                home / 'Library' / 'Caches' / 'ms-playwright',  # macOS
            ]
            
            for base_path in possible_paths:
                if base_path.exists():
                    # Look for any chromium installation
                    chromium_dirs = list(base_path.glob('chromium*'))
                    if chromium_dirs:
                        # Check if executable exists
                        for chromium_dir in chromium_dirs:
                            if (chromium_dir / 'chrome-linux' / 'chrome').exists() or \
                               (chromium_dir / 'chrome-linux' / 'headless_shell').exists() or \
                               (chromium_dir / 'chrome-mac' / 'Chromium.app').exists() or \
                               (chromium_dir / 'chrome-win' / 'chrome.exe').exists():
                                browser_installed = True
                                break
                if browser_installed:
                    break
            
            if browser_installed:
                print("✅ Przeglądarka Chromium już zainstalowana")
            else:
                # Browsers not installed
                if not auto_install:
                    print("⚠️  Brak przeglądarek Playwright")
                    print("💡 Zainstaluj: playwright install chromium")
                    return False
                
                print("\n🌐 Instaluję przeglądarki Playwright (może potrwać ~100MB)...")
                print("   To może zająć 1-2 minuty...")
                cmd = [sys.executable, '-m', 'playwright', 'install', 'chromium']
                result = subprocess.run(cmd, check=True, capture_output=False, text=True)
                print("✅ Zainstalowano przeglądarkę Chromium")
        except Exception as e:
            print(f"⚠️  Nie udało się sprawdzić/zainstalować przeglądarek: {e}")
            print("💡 Spróbuj ręcznie: playwright install chromium")
            # Don't return False - browsers might already be installed
    
    return True


def main():
    """Główny entry point dla llmass CLI"""
    # Załaduj zmienne środowiskowe z .env
    load_dotenv()
    parser = argparse.ArgumentParser(
        prog='llmass',
        description='AI-powered email management and automation system',
        epilog='Użyj "llmass <komenda> --help" dla szczegółów każdej komendy'
    )
    
    subparsers = parser.add_subparsers(
        dest='command',
        help='Dostępne komendy',
        required=True
    )
    
    # === llmass generate (email generator) ===
    generate_parser = subparsers.add_parser(
        'generate',
        help='Generuj testowe emaile',
        description='Generowanie testowych emaili dla środowiska testowego'
    )
    generate_parser.add_argument('--smtp-host', default='localhost', help='Host SMTP')
    generate_parser.add_argument('--smtp-port', type=int, default=1025, help='Port SMTP')
    generate_parser.add_argument('--num-emails', type=int, help='Liczba emaili do wygenerowania')
    generate_parser.add_argument('--spam-ratio', type=float, help='Proporcja spamu (0-1)')
    generate_parser.add_argument('--to', help='Adres odbiorcy')
    
    # === llmass clean (email organizer) ===
    clean_parser = subparsers.add_parser(
        'clean',
        help='Organizuj i kategoryzuj emaile',
        description='Automatyczne grupowanie, kategoryzacja i usuwanie spamu'
    )
    clean_parser.add_argument('--email', help='Adres email')
    clean_parser.add_argument('--password', help='Hasło')
    clean_parser.add_argument('--server', help='Serwer IMAP')
    clean_parser.add_argument('--dry-run', action='store_true', help='Tryb testowy (bez zmian)')
    clean_parser.add_argument('--limit', type=int, help='Limit emaili do przetworzenia')
    clean_parser.add_argument('--since-days', type=int, help='Ile dni wstecz')
    clean_parser.add_argument('--since-date', help='Data początkowa (YYYY-MM-DD)')
    clean_parser.add_argument('--folder', default='INBOX', help='Folder do przetworzenia')
    clean_parser.add_argument('--include-subfolders', action='store_true', help='Przetwarzaj podfoldery')
    clean_parser.add_argument('--similarity-threshold', type=float, help='Próg podobieństwa (0-1)')
    clean_parser.add_argument('--min-cluster-size', type=int, help='Minimalny rozmiar klastra')
    clean_parser.add_argument('--min-cluster-fraction', type=float, help='Minimalny udział klastra (0-1)')
    clean_parser.add_argument('--verbose', '-v', action='store_true', help='Tryb verbose - pokaż wszystkie szczegóły')
    
    # === llmass write (email responder) ===
    write_parser = subparsers.add_parser(
        'write',
        help='Generuj odpowiedzi AI na emaile',
        description='Automatyczne tworzenie odpowiedzi z użyciem LLM'
    )
    write_parser.add_argument('--email', help='Adres email')
    write_parser.add_argument('--password', help='Hasło')
    write_parser.add_argument('--server', help='Serwer IMAP')
    write_parser.add_argument('--smtp', help='Serwer SMTP')
    write_parser.add_argument('--model', help='Model LLM (domyślnie: Qwen/Qwen2.5-7B-Instruct)')
    write_parser.add_argument('--folder', default='INBOX', help='Folder do przetworzenia')
    write_parser.add_argument('--limit', type=int, help='Limit emaili')
    write_parser.add_argument('--since-days', type=int, help='Ile dni wstecz')
    write_parser.add_argument('--since-date', help='Data początkowa (YYYY-MM-DD)')
    write_parser.add_argument('--all-emails', action='store_true', help='Przetwarzaj wszystkie (nie tylko nieprzeczytane)')
    write_parser.add_argument('--dry-run', action='store_true', help='Nie zapisuj draftów')
    write_parser.add_argument('--temperature', type=float, help='Temperatura generowania (0-1)')
    write_parser.add_argument('--max-tokens', type=int, help='Maksymalna długość odpowiedzi')
    write_parser.add_argument('--offline', action='store_true', help='Tryb offline (mock responses)')
    
    # === llmass repair ===
    repair_parser = subparsers.add_parser(
        'repair',
        help='Napraw corruption skrzynki IMAP',
        description='Automatyczna naprawa uszkodzonych UIDs w skrzynce IMAP'
    )
    repair_parser.add_argument('--email', help='Adres email')
    repair_parser.add_argument('--password', help='Hasło')
    repair_parser.add_argument('--server', help='Serwer IMAP')
    repair_parser.add_argument('--folder', default='INBOX', help='Folder do naprawy')
    repair_parser.add_argument('--dry-run', action='store_true', help='Tryb testowy (bez zmian)')
    repair_parser.add_argument('--force', action='store_true', help='Wymusza naprawę bez potwierdzenia')
    
    # === llmass unsubscribe ===
    unsub_parser = subparsers.add_parser(
        'unsubscribe',
        help='Automatyczne wypisywanie z newsletterów',
        description='Znajdź i wypisz się z newsletterów używając wirtualnej przeglądarki'
    )
    unsub_parser.add_argument('--email', help='Adres email')
    unsub_parser.add_argument('--password', help='Hasło')
    unsub_parser.add_argument('--server', help='Serwer IMAP')
    unsub_parser.add_argument('--folder', default='SPAM', help='Folder do przeszukania (domyślnie: SPAM)')
    unsub_parser.add_argument('--limit', type=int, default=100, help='Limit emaili do sprawdzenia')
    unsub_parser.add_argument('--since-days', type=int, default=30, help='Ile dni wstecz')
    unsub_parser.add_argument('--dry-run', action='store_true', help='Tylko znajdź, nie wypisuj')
    unsub_parser.add_argument('--no-headless', action='store_true', help='Pokaż przeglądarkę')
    unsub_parser.add_argument('--open-browser', action='store_true', help='Otwórz linki również w domyślnej przeglądarce')
    unsub_parser.add_argument('--no-dedupe', action='store_true', help='Nie deduplikuj po nadawcy')
    unsub_parser.add_argument('--stats', action='store_true', help='Pokaż tylko statystyki')
    
    # === llmass spam-ui ===
    spam_ui_parser = subparsers.add_parser(
        'spam-ui',
        help='Web UI do zarządzania spamem',
        description='Uruchom interfejs webowy do szybkiego zarządzania spamem'
    )
    spam_ui_parser.add_argument('--port', type=int, default=5001, help='Port serwera (domyślnie: 5001)')
    spam_ui_parser.add_argument('--host', default='0.0.0.0', help='Host serwera (domyślnie: 0.0.0.0)')
    
    # === llmass web ===
    web_parser = subparsers.add_parser(
        'web',
        help='Web Dashboard - zarządzaj wszystkimi komendami',
        description='Uruchom Web Dashboard do zarządzania wszystkimi funkcjami LLMass'
    )
    web_parser.add_argument('--port', type=int, default=5002, help='Port serwera (domyślnie: 5002)')
    web_parser.add_argument('--host', default='0.0.0.0', help='Host serwera (domyślnie: 0.0.0.0)')
    
    # === llmass test ===
    test_parser = subparsers.add_parser(
        'test',
        help='Uruchom testy jednostkowe',
        description='Testy funkcjonalności llmass'
    )
    test_parser.add_argument('--verbose', '-v', action='store_true', help='Tryb verbose')
    test_parser.add_argument('--quick', action='store_true', help='Szybkie testy (bez integracyjnych)')
    
    args = parser.parse_args()
    
    # Wywołaj odpowiednią komendę
    if args.command == 'generate':
        run_generate(args)
    elif args.command == 'clean':
        run_clean(args)
    elif args.command == 'write':
        run_write(args)
    elif args.command == 'repair':
        run_repair(args)
    elif args.command == 'unsubscribe':
        run_unsubscribe(args)
    elif args.command == 'spam-ui':
        run_spam_ui(args)
    elif args.command == 'web':
        run_web_dashboard(args)
    elif args.command == 'test':
        run_test(args)
    else:
        parser.print_help()
        sys.exit(1)


def run_clean(args):
    """Uruchom email organizer"""
    try:
        from llmass.organizer.app import run_clean_from_args
        run_clean_from_args(args)
    except Exception as e:
        print(f"⚠️  Modułowy organizer niedostępny ({e}), używam bezpośredniego wywołania...")
        # Fallback to direct email_organizer call
        try:
            from email_organizer import main as organizer_main
        except ImportError as ie:
            print(f"❌ Nie można zaimportować email_organizer: {ie}")
            print("💡 Sugestie:")
            print("   1. Zainstaluj zależności: pip install scikit-learn numpy")
            print("   2. Lub użyj venv: source venv/bin/activate && llmass clean")
            print("   3. Lub tylko email responder: llmass write --help")
            sys.exit(1)
        
        # Przekaż argumenty do email_organizer
        sys.argv = ['email_organizer']
        if args.email:
            sys.argv.extend(['--email', args.email])
        if args.password:
            sys.argv.extend(['--password', args.password])
        if args.server:
            sys.argv.extend(['--server', args.server])
        if args.dry_run:
            sys.argv.append('--dry-run')
        if args.limit:
            sys.argv.extend(['--limit', str(args.limit)])
        if args.since_days:
            sys.argv.extend(['--since-days', str(args.since_days)])
        if args.since_date:
            sys.argv.extend(['--since-date', args.since_date])
        if args.folder:
            sys.argv.extend(['--folder', args.folder])
        if args.include_subfolders:
            sys.argv.append('--include-subfolders')
        if args.similarity_threshold:
            sys.argv.extend(['--similarity-threshold', str(args.similarity_threshold)])
        if args.min_cluster_size:
            sys.argv.extend(['--min-cluster-size', str(args.min_cluster_size)])
        if args.min_cluster_fraction:
            sys.argv.extend(['--min-cluster-fraction', str(args.min_cluster_fraction)])
        if args.verbose:
            sys.argv.append('--verbose')
        
        organizer_main()


def run_write(args):
    """Uruchom email responder"""
    try:
        from email_responder import main as responder_main
    except ImportError:
        print("❌ Nie można zaimportować email_responder")
        sys.exit(1)
    
    # Przekaż argumenty do email_responder
    sys.argv = ['email_responder']
    if args.email:
        sys.argv.extend(['--email', args.email])
    if args.password:
        sys.argv.extend(['--password', args.password])
    if args.server:
        sys.argv.extend(['--server', args.server])
    if args.smtp:
        sys.argv.extend(['--smtp', args.smtp])
    if args.model:
        sys.argv.extend(['--model', args.model])
    if args.folder:
        sys.argv.extend(['--folder', args.folder])
    if args.limit:
        sys.argv.extend(['--limit', str(args.limit)])
    if args.since_days:
        sys.argv.extend(['--since-days', str(args.since_days)])
    if args.since_date:
        sys.argv.extend(['--since-date', args.since_date])
    if args.all_emails:
        sys.argv.append('--all-emails')
    if args.dry_run:
        sys.argv.append('--dry-run')
    if args.temperature:
        sys.argv.extend(['--temperature', str(args.temperature)])
    if args.max_tokens:
        sys.argv.extend(['--max-tokens', str(args.max_tokens)])
    if args.offline:
        sys.argv.append('--offline')
    
    responder_main()


def run_generate(args):
    """Uruchom generator emaili"""
    try:
        from email_generator import main as generator_main
    except ImportError:
        print("❌ Nie można zaimportować email_generator")
        sys.exit(1)
    
    # Przekaż argumenty do email_generator
    sys.argv = ['email_generator']
    if args.smtp_host:
        sys.argv.extend(['--smtp-host', args.smtp_host])
    if args.smtp_port:
        sys.argv.extend(['--smtp-port', str(args.smtp_port)])
    if args.num_emails:
        sys.argv.extend(['--num-emails', str(args.num_emails)])
    if args.spam_ratio:
        sys.argv.extend(['--spam-ratio', str(args.spam_ratio)])
    if args.to:
        sys.argv.extend(['--to', args.to])
    
    generator_main()


def run_repair(args):
    """Uruchom naprawę corruption IMAP"""
    try:
        from email_organizer import main as organizer_main
        import sys
        
        # Przekaż argumenty do email_organizer
        original_argv = sys.argv.copy()
        sys.argv = ['email_organizer', '--repair']
        
        if args.email:
            sys.argv.extend(['--email', args.email])
        if args.password:
            sys.argv.extend(['--password', args.password])
        if args.server:
            sys.argv.extend(['--server', args.server])
        if args.folder:
            sys.argv.extend(['--folder', args.folder])
        if args.dry_run:
            sys.argv.append('--dry-run')
        if args.force:
            sys.argv.append('--force')
        
        organizer_main()
        
    except Exception as e:
        print(f"❌ Błąd podczas naprawy: {e}")
        sys.exit(1)
    finally:
        sys.argv = original_argv


def run_unsubscribe(args):
    """Uruchom automatyczne wypisywanie z newsletterów"""
    # Check and install dependencies
    required_packages = ['playwright', 'beautifulsoup4']
    if not check_and_install_dependencies(required_packages, install_browsers=True):
        print("❌ Nie można zainstalować wymaganych zależności")
        sys.exit(1)
    
    # Add current directory to path for email_unsubscriber import
    current_dir = os.path.dirname(os.path.abspath(__file__))
    if current_dir not in sys.path:
        sys.path.insert(0, current_dir)
    
    try:
        from email_unsubscriber import EmailUnsubscriber, UnsubscribeLogger
        
        if args.stats:
            # Show stats only
            logger = UnsubscribeLogger()
            stats = logger.generate_stats()
            print(f"\n📈 STATYSTYKI UNSUBSCRIBE:")
            print(f"   Łącznie prób: {stats['total']}")
            print(f"   Sukcesy: {stats['success']}")
            print(f"   Niepowodzenia: {stats['failed']}")
            print(f"   Skuteczność: {stats['success_rate']}%\n")
            
            failed_senders = logger.get_failed_senders()
            if failed_senders:
                print(f"❌ Nadawcy z nieudanymi próbami ({len(failed_senders)}):")
                for sender in failed_senders[:10]:
                    print(f"   - {sender}")
            sys.exit(0)
        
        email = args.email or os.getenv('EMAIL_ADDRESS')
        password = args.password or os.getenv('EMAIL_PASSWORD')
        imap_server = args.server or os.getenv('IMAP_SERVER')
        
        if not email or not password:
            print("❌ Brak danych logowania. Podaj --email/--password lub .env")
            sys.exit(1)
        
        unsubscriber = EmailUnsubscriber(email, password, imap_server)
        
        if unsubscriber.connect():
            try:
                # Find newsletters
                newsletters = unsubscriber.find_newsletters(
                    folder=args.folder,
                    limit=args.limit,
                    since_days=args.since_days,
                    deduplicate=not args.no_dedupe
                )
                
                if newsletters:
                    # Unsubscribe
                    results = unsubscriber.unsubscribe_all(
                        newsletters,
                        headless=not args.no_headless,
                        dry_run=args.dry_run,
                        open_in_browser=args.open_browser
                    )
            finally:
                unsubscriber.disconnect()
    
    except ImportError as e:
        print(f"❌ Nie można zaimportować email_unsubscriber: {e}")
        print("💡 Sugestie:")
        print("   1. Zainstaluj zależności: pip install playwright beautifulsoup4")
        print("   2. Zainstaluj Playwright browsers: playwright install chromium")
        sys.exit(1)
    except Exception as e:
        print(f"❌ Błąd podczas unsubscribe: {e}")
        sys.exit(1)


def run_spam_ui(args):
    """Uruchom Web UI do zarządzania spamem"""
    # Check and install dependencies
    required_packages = ['flask', 'playwright', 'pillow']
    if not check_and_install_dependencies(required_packages, install_browsers=True):
        print("❌ Nie można zainstalować wymaganych zależności")
        sys.exit(1)
    
    # Add current directory to path for spam_manager_ui import
    current_dir = os.path.dirname(os.path.abspath(__file__))
    if current_dir not in sys.path:
        sys.path.insert(0, current_dir)
    
    try:
        from spam_manager_ui import app, email_address, password, imap_server, connect
        
        # Check credentials
        email = os.getenv('EMAIL_ADDRESS')
        pwd = os.getenv('EMAIL_PASSWORD')
        
        if not email or not pwd:
            print("❌ Brak danych logowania w .env")
            print("💡 Ustaw EMAIL_ADDRESS i EMAIL_PASSWORD")
            sys.exit(1)
        
        print(f"🚀 Starting Spam Manager UI...")
        print(f"📧 Email: {email}")
        print(f"🌐 URL: http://localhost:{args.port}")
        print(f"📁 Folder: SPAM")
        print(f"\n💡 Otwórz w przeglądarce: http://localhost:{args.port}")
        print(f"   Ctrl+C aby zatrzymać\n")
        
        # Import here to set globals before running
        import spam_manager_ui
        spam_manager_ui.email_address = email
        spam_manager_ui.password = pwd
        spam_manager_ui.imap_server = os.getenv('IMAP_SERVER')
        
        if not spam_manager_ui.connect():
            print("❌ Nie można połączyć z serwerem IMAP")
            sys.exit(1)
        
        spam_manager_ui.app.run(host=args.host, port=args.port, debug=False)
    
    except ImportError as e:
        print(f"❌ Nie można zaimportować spam_manager_ui: {e}")
        print("💡 Zainstaluj zależności: pip install flask playwright pillow")
        print("   playwright install chromium")
        sys.exit(1)
    except Exception as e:
        print(f"❌ Błąd: {e}")
        sys.exit(1)


def run_web_dashboard(args):
    """Uruchom Web Dashboard do zarządzania wszystkimi komendami"""
    # Check and install dependencies
    required_packages = ['flask']
    if not check_and_install_dependencies(required_packages, install_browsers=False):
        print("❌ Nie można zainstalować wymaganych zależności")
        sys.exit(1)
    
    # Add current directory to path for web_dashboard import
    current_dir = os.path.dirname(os.path.abspath(__file__))
    if current_dir not in sys.path:
        sys.path.insert(0, current_dir)
    
    try:
        from web_dashboard import app
        
        print(f"🚀 Starting LLMass Web Dashboard...")
        print(f"📧 Email: {os.getenv('EMAIL_ADDRESS', 'Not set')}")
        print(f"🌐 URL: http://localhost:{args.port}")
        print(f"\n💡 Otwórz w przeglądarce: http://localhost:{args.port}")
        print(f"   Zarządzaj wszystkimi komendami LLMass z jednego miejsca")
        print(f"   Ctrl+C aby zatrzymać\n")
        
        app.run(host=args.host, port=args.port, debug=False)
    
    except ImportError as e:
        print(f"❌ Nie można zaimportować web_dashboard: {e}")
        print("💡 Zainstaluj zależności: pip install flask")
        sys.exit(1)
    except Exception as e:
        print(f"❌ Błąd: {e}")
        sys.exit(1)


def run_test(args):
    """Uruchom testy"""
    try:
        import pytest
    except ImportError:
        print("❌ pytest nie jest zainstalowany. Zainstaluj: pip install pytest")
        sys.exit(1)
    
    pytest_args = ['test_suite.py']
    if args.verbose:
        pytest_args.append('-v')
    if args.quick:
        pytest_args.extend(['-m', 'not slow'])
    
    sys.exit(pytest.main(pytest_args))


if __name__ == '__main__':
    main()
