#!/usr/bin/env python3
"""
Jarvis AI - Основной CLI интерфейс
Версия без эмодзи и без мыши/клавиатуры для совместимости с Windows
"""
import sys
import os
import argparse
from pathlib import Path
from datetime import datetime

class JarvisCLI:
    """Главный класс CLI для Jarvis AI"""
    
    def __init__(self):
        self.km = self._init_knowledge_manager()
        self.fm = self._init_file_manager()
        self.screen_analyzer = self._init_screen_analyzer()
    
    def _init_knowledge_manager(self):
        """Инициализация менеджера знаний"""
        try:
            from jarvis_ai.core.knowledge_manager import KnowledgeManager
            return KnowledgeManager()
        except ImportError:
            return None
    
    def _init_file_manager(self):
        """Инициализация файлового менеджера"""
        try:
            from jarvis_ai.system.file_manager import FileManager
            return FileManager()
        except ImportError:
            return None

    def _init_screen_analyzer(self):
        """Инициализация анализатора экрана"""
        try:
            from jarvis_ai.system.screen_analyzer import ScreenAnalyzer
            return ScreenAnalyzer(self.fm) if self.fm else None
        except ImportError:
            return None
    
    def main(self):
        """Основная точка входа"""
        parser = self._create_parser()
        args = parser.parse_args()
        
        if not args.command:
            self._show_main_help()
            return
        
        self._handle_command(args)
    
    def _create_parser(self):
        """Создание парсера аргументов"""
        parser = argparse.ArgumentParser(
            description='Jarvis AI - Персональный AI ассистент с полным доступом к системе',
            add_help=False
        )
        
        subparsers = parser.add_subparsers(dest='command', help='Доступные команды')
        
        # Основные команды
        self._add_main_commands(subparsers)
        
        # Файловые команды
        self._add_file_commands(subparsers)
        
        # Команды знаний
        self._add_knowledge_commands(subparsers)
        
        # Служебные команды
        self._add_utility_commands(subparsers)
        
        return parser
    
    def _add_main_commands(self, subparsers):
        """Добавление основных команд"""
        subparsers.add_parser('start', help='Запуск интерактивного режима с нейросетью')
        subparsers.add_parser('stats', help='Показать статистику системы знаний')
        subparsers.add_parser('open-data', help='Открыть папку с данными Jarvis')
        
        search_parser = subparsers.add_parser('search', help='Поиск в базе знаний')
        search_parser.add_argument('query', help='Поисковый запрос')

        # Анализ проблем на экране
        analyze_parser = subparsers.add_parser('analyze', help='Анализ проблем на экране')
        analyze_parser.add_argument('problem', help='Описание проблемы для анализа')
        
        # Показать последние скриншоты
        screenshots_parser = subparsers.add_parser('screenshots', help='Показать последние скриншоты')
        screenshots_parser.add_argument('--limit', type=int, default=5, help='Количество скриншотов для показа')
    
    def _add_file_commands(self, subparsers):
        """Добавление файловых команд"""
        file_parser = subparsers.add_parser('file', help='Операции с файлами и директориями')
        file_subparsers = file_parser.add_subparsers(dest='file_command', help='Файловые операции')
        
        # List files
        list_parser = file_subparsers.add_parser('list', help='Список файлов в директории')
        list_parser.add_argument('path', nargs='?', default='.', help='Путь для списка')
        list_parser.add_argument('--hidden', action='store_true', help='Показать скрытые файлы')
        
        # Change directory
        cd_parser = file_subparsers.add_parser('cd', help='Сменить текущую директорию')
        cd_parser.add_argument('path', help='Новый путь')
        
        # Create directory
        mkdir_parser = file_subparsers.add_parser('mkdir', help='Создать новую директорию')
        mkdir_parser.add_argument('name', help='Имя директории')
        mkdir_parser.add_argument('--path', help='Путь для создания')
        
        # Create file
        touch_parser = file_subparsers.add_parser('touch', help='Создать новый файл')
        touch_parser.add_argument('name', help='Имя файла')
        touch_parser.add_argument('--content', default='', help='Содержимое файла')
        touch_parser.add_argument('--path', help='Путь для создания')
        
        # Delete
        rm_parser = file_subparsers.add_parser('rm', help='Удалить файл или директорию')
        rm_parser.add_argument('path', help='Путь для удаления')
        rm_parser.add_argument('-r', '--recursive', action='store_true', help='Рекурсивное удаление директорий')
        
        # Copy
        cp_parser = file_subparsers.add_parser('cp', help='Копировать файл или директорию')
        cp_parser.add_argument('source', help='Источник для копирования')
        cp_parser.add_argument('destination', help='Назначение для копирования')
        
        # Move
        mv_parser = file_subparsers.add_parser('mv', help='Переместить файл или директорию')
        mv_parser.add_argument('source', help='Источник для перемещения')
        mv_parser.add_argument('destination', help='Назначение для перемещения')
        
        # Search files
        find_parser = file_subparsers.add_parser('find', help='Поиск файлов по шаблону')
        find_parser.add_argument('pattern', help='Шаблон поиска')
        find_parser.add_argument('--dir', help='Директория для поиска')
        find_parser.add_argument('--no-recursive', action='store_true', help='Отключить рекурсивный поиск')
        
        # File info
        info_parser = file_subparsers.add_parser('info', help='Полная информация о файле или директории')
        info_parser.add_argument('path', help='Путь к файлу или директории')
        
        # Disk usage
        disk_parser = file_subparsers.add_parser('disk', help='Информация об использовании диска')
        
        # Current directory
        pwd_parser = file_subparsers.add_parser('pwd', help='Показать текущую директорию')
        
        # File content
        cat_parser = file_subparsers.add_parser('cat', help='Показать содержимое файла')
        cat_parser.add_argument('path', help='Путь к файлу')
        
        # Screenshot command
        screenshot_parser = file_subparsers.add_parser('screenshot', help='Сделать скриншот')
        screenshot_parser.add_argument('--path', help='Путь для сохранения скриншота')
        
        # File help
        help_parser = file_subparsers.add_parser('help', help='Показать справку по файловым командам')
    
    def _add_knowledge_commands(self, subparsers):
        """Добавление команд для работы со знаниями"""
        knowledge_parser = subparsers.add_parser('knowledge', help='Работа с системой знаний')
        knowledge_subparsers = knowledge_parser.add_subparsers(dest='knowledge_command', help='Команды знаний')
        
        # Import data
        import_parser = knowledge_subparsers.add_parser('import', help='Импорт данных в систему знаний')
        import_parser.add_argument('file_path', help='Путь к файлу для импорта')
        
        # Create topic
        topic_parser = knowledge_subparsers.add_parser('create-topic', help='Создать новую тему')
        topic_parser.add_argument('name', help='Название темы')
        topic_parser.add_argument('content', help='Содержимое темы')
        topic_parser.add_argument('--tags', nargs='+', help='Теги для темы')
        
        # List topics
        list_parser = knowledge_subparsers.add_parser('list-topics', help='Список всех тем')
        
        # Knowledge help
        help_parser = knowledge_subparsers.add_parser('help', help='Показать справку по командам знаний')
    
    def _add_utility_commands(self, subparsers):
        """Добавление служебных команды"""
        subparsers.add_parser('version', help='Показать версию Jarvis AI')
        subparsers.add_parser('help', help='Показать эту справку')
        subparsers.add_parser('test', help='Запустить тесты системы')
    
    def _handle_command(self, args):
        """Обработка всех команд"""
        command_handlers = {
            'start': self._handle_start,
            'stats': self._handle_stats,
            'search': lambda: self._handle_search(args.query),
            'open-data': self._handle_open_data,
            'file': lambda: self._handle_file_command(args),
            'knowledge': lambda: self._handle_knowledge_command(args),
            'version': self._handle_version,
            'help': self._handle_help,
            'test': self._handle_test,
            'analyze': lambda: self._handle_analyze(args.problem),
            'screenshots': lambda: self._handle_screenshots(args.limit),
        }
        
        handler = command_handlers.get(args.command)
        if handler:
            try:
                handler()
            except Exception as e:
                print(f"Ошибка выполнения команды: {e}")
        else:
            print(f"Неизвестная команда: {args.command}")
            self._show_main_help()
    
    def _handle_start(self):
        """Обработка команды start"""
        print("Запуск Jarvis AI...")
        print("Режим нейросети будет добавлен в следующих версиях")
        print("Сейчас доступны команды через CLI")
    
    def _handle_stats(self):
        """Обработка команды stats"""
        if not self.km:
            print("Система знаний не доступна")
            return
        
        stats = self.km.get_stats()
        print("Статистика системы знаний:")
        print(f"  Темы в базе: {stats['total_topics']}")
        print(f"  Файлов данных: {stats['total_files']}")
        print(f"  Путь к данным: {stats['data_path']}")
    
    def _handle_search(self, query):
        """Обработка команды search"""
        if not self.km:
            print("Система знаний не доступна")
            return
        
        if not query:
            print("Укажите поисковый запрос")
            print("  Использование: jarvis search <запрос>")
            return
        
        print(f"Поиск: '{query}'")
        results = self.km.search(query)
        
        if results:
            print(f"Найдено результатов: {len(results)}")
            for i, result in enumerate(results[:5], 1):
                print(f"  {i}. {result['name']}")
        else:
            print("Ничего не найдено")
    
    def _handle_open_data(self):
        """Обработка команды open-data"""
        data_path = Path.home() / ".jarvis_data"
        data_path.mkdir(exist_ok=True)
        
        print(f"Открытие папки данных: {data_path}")
        
        try:
            if sys.platform == "win32":
                os.startfile(data_path)
            elif sys.platform == "darwin":
                os.system(f'open "{data_path}"')
            else:
                os.system(f'xdg-open "{data_path}"')
            print("Папка открыта")
        except Exception as e:
            print(f"Не удалось открыть папку: {e}")
    
    def _handle_file_command(self, args):
        """Обработка файловых команд"""
        if not self.fm:
            print("Файловый менеджер не доступен")
            return
        
        if not args.file_command:
            self._show_file_help()
            return
        
        file_handlers = {
            'list': lambda: self._handle_file_list(args.path, args.hidden),
            'cd': lambda: self._handle_file_cd(args.path),
            'mkdir': lambda: self._handle_file_mkdir(args.name, args.path),
            'touch': lambda: self._handle_file_touch(args.name, args.content, args.path),
            'rm': lambda: self._handle_file_rm(args.path, args.recursive),
            'cp': lambda: self._handle_file_cp(args.source, args.destination),
            'mv': lambda: self._handle_file_mv(args.source, args.destination),
            'find': lambda: self._handle_file_find(args.pattern, args.dir, not args.no_recursive),
            'info': lambda: self._handle_file_info(args.path),
            'disk': self._handle_file_disk,
            'pwd': self._handle_file_pwd,
            'cat': lambda: self._handle_file_cat(args.path),
            'screenshot': lambda: self._handle_file_screenshot(args.path),
            'help': self._show_file_help
        }
        
        handler = file_handlers.get(args.file_command)
        if handler:
            try:
                handler()
            except Exception as e:
                print(f"Файловая ошибка: {e}")
        else:
            print(f"Неизвестная файловая команда: {args.file_command}")
            self._show_file_help()
    
    def _handle_knowledge_command(self, args):
        """Обработка команд знаний"""
        if not self.km:
            print("Система знаний не доступна")
            return
        
        if not args.knowledge_command:
            self._show_knowledge_help()
            return
        
        knowledge_handlers = {
            'import': lambda: self._handle_knowledge_import(args.file_path),
            'create-topic': lambda: self._handle_knowledge_create_topic(args.name, args.content, args.tags),
            'list-topics': self._handle_knowledge_list_topics,
            'help': self._show_knowledge_help
        }
        
        handler = knowledge_handlers.get(args.knowledge_command)
        if handler:
            try:
                handler()
            except Exception as e:
                print(f"Ошибка знаний: {e}")
        else:
            print(f"Неизвестная команда знаний: {args.knowledge_command}")
            self._show_knowledge_help()
    
    def _handle_version(self):
        """Обработка команды version"""
        try:
            from jarvis_ai import __version__
            print(f"Jarvis AI v{__version__}")
        except ImportError:
            print("Jarvis AI v0.1.0")
    
    def _handle_help(self):
        """Обработка команды help"""
        self._show_main_help()
    
    def _handle_test(self):
        """Обработка команды test"""
        print("Запуск тестов системы...")
        self._run_system_tests()

    def _handle_analyze(self, problem_description):
        """Обработка анализа проблемы на экране"""
        if not self.screen_analyzer:
            print("Анализатор экрана не доступен")
            return
        
        print(f"Анализируем проблему: '{problem_description}'")
        print("Делаем скриншот...")
        
        result = self.screen_analyzer.analyze_ui_problem(problem_description)
        
        if isinstance(result, dict):
            print(f"Скриншот сохранен: {result['screenshot_path']}")
            print(f"Анализ: {result['analysis']}")
            print("Рекомендуемые действия:")
            for i, action in enumerate(result['suggested_actions'], 1):
                print(f"   {i}. {action}")
        else:
            print(result)

    def _handle_screenshots(self, limit):
        """Обработка показа последних скриншотов"""
        if not self.screen_analyzer:
            print("Анализатор экрана не доступен")
            return
        
        screenshots = self.screen_analyzer.get_recent_screenshots(limit)
        
        if not screenshots:
            print("Скриншотов не найдено")
            return
        
        print(f"Последние {len(screenshots)} скриншотов:")
        for i, screenshot in enumerate(screenshots, 1):
            print(f"   {i}. {screenshot['filename']}")
            print(f"      Создан: {screenshot['created'].strftime('%Y-%m-%d %H:%M:%S')}")
            print(f"      Путь: {screenshot['path']}")
    
    # Файловые обработчики
    def _handle_file_list(self, path, show_hidden):
        """Обработка списка файлов"""
        items = self.fm.list_directory(path, show_hidden)
        print(f"Содержимое: {self.fm.get_current_directory()}")
        print("-" * 60)
        for item in items:
            icon = "[DIR]" if item['type'] == 'directory' else "[FILE]"
            size = self.fm._human_readable_size(item['size']) if item['type'] == 'file' else "<DIR>"
            modified = item['modified'].strftime("%Y-%m-%d %H:%M")
            print(f"{icon} {item['name']:<30} {size:>10} {modified}")
    
    def _handle_file_cd(self, path):
        """Обработка смены директории"""
        new_path = self.fm.change_directory(path)
        print(f"Текущая директория: {new_path}")
    
    def _handle_file_mkdir(self, name, path):
        """Обработка создания директории"""
        new_dir = self.fm.create_directory(name, path)
        print(f"Создана директория: {new_dir}")
    
    def _handle_file_touch(self, name, content, path):
        """Обработка создания файла"""
        new_file = self.fm.create_file(name, content, path)
        print(f"Создан файл: {new_file}")
    
    def _handle_file_rm(self, path, recursive):
        """Обработка удаления"""
        success = self.fm.delete_path(path, recursive)
        if success:
            print(f"Удалено: {path}")
    
    def _handle_file_cp(self, source, destination):
        """Обработка копирования"""
        new_path = self.fm.copy_path(source, destination)
        print(f"Скопировано в: {new_path}")
    
    def _handle_file_mv(self, source, destination):
        """Обработка перемещения"""
        new_path = self.fm.move_path(source, destination)
        print(f"Перемещено в: {new_path}")
    
    def _handle_file_find(self, pattern, search_dir, recursive):
        """Обработка поиска файлов"""
        results = self.fm.search_files(pattern, search_dir, recursive)
        print(f"Найдено файлов: {len(results)}")
        for result in results:
            icon = "[DIR]" if result['type'] == 'directory' else "[FILE]"
            print(f"{icon} {result['path']}")
    
    def _handle_file_info(self, path):
        """Обработка информации о файле"""
        info = self.fm.get_file_info(path)
        print(f"Информация о: {info['name']}")
        print(f"  Путь: {info['absolute_path']}")
        print(f"  Тип: {info['type']}")
        print(f"  Размер: {info['size_human']}")
        print(f"  Создан: {info['created'].strftime('%Y-%m-%d %H:%M:%S')}")
        print(f"  Изменен: {info['modified'].strftime('%Y-%m-%d %H:%M:%S')}")
        print(f"  Права: {info['permissions']}")
    
    def _handle_file_disk(self):
        """Обработка информации о диске"""
        usage = self.fm.get_disk_usage()
        print("Использование диска:")
        print(f"  Путь: {usage['path']}")
        print(f"  Всего: {usage['total_human']}")
        print(f"  Использовано: {usage['used_human']} ({usage['usage_percent']:.1f}%)")
        print(f"  Свободно: {usage['free_human']}")
    
    def _handle_file_pwd(self):
        """Обработка текущей директории"""
        print(f"Текущая директория: {self.fm.get_current_directory()}")
    
    def _handle_file_cat(self, path):
        """Обработка показа содержимого файла"""
        content = self.fm.read_file_content(path)
        print(f"Содержимое {path}:")
        print("-" * 40)
        print(content)
    
    def _handle_file_screenshot(self, save_path):
        """Обработка создания скриншота"""
        try:
            if not save_path:
                # Создаем автоматическое имя файла
                timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
                save_path = f"screenshot_{timestamp}.png"
            
            screenshot = self.fm.capture_screenshot(save_path)
            print(f"Скриншот сохранен: {save_path}")
            return screenshot
        except Exception as e:
            print(f"Ошибка создания скриншота: {e}")
    
    # Обработчики знаний
    def _handle_knowledge_import(self, file_path):
        """Обработка импорта знаний"""
        print(f"Импорт файла: {file_path}")
        # Здесь будет логика импорта
        print("Файл принят в обработку")
    
    def _handle_knowledge_create_topic(self, name, content, tags):
        """Обработка создания темы"""
        topic_id = self.km.create_topic(name, content, tags)
        print(f"Создана тема: {name} (ID: {topic_id})")
    
    def _handle_knowledge_list_topics(self):
        """Обработка списка тем"""
        print("Все темы в системе:")
        # Здесь будет логика списка тем
        print("Система тем в разработке")
    
    # Системные тесты
    def _run_system_tests(self):
        """Запуск комплексных тестов системы"""
        tests = [
            ("Основные команды", self._test_basic_commands),
            ("Файловый менеджер", self._test_file_manager),
            ("Система знаний", self._test_knowledge_system),
        ]
        
        print("ЗАПУСК КОМПЛЕКСНЫХ ТЕСТОВ СИСТЕМЫ")
        print("=" * 50)
        
        total_tests = 0
        passed_tests = 0
        
        for test_name, test_func in tests:
            print(f"\nТест: {test_name}")
            print("-" * 30)
            try:
                passed, total = test_func()
                passed_tests += passed
                total_tests += total
                print(f"Пройдено: {passed}/{total}")
            except Exception as e:
                print(f"Тест упал с ошибкой: {e}")
        
        print("\n" + "=" * 50)
        print(f"ИТОГИ ТЕСТИРОВАНИЯ:")
        print(f"Пройдено тестов: {passed_tests}/{total_tests}")
        
        if passed_tests == total_tests:
            print("ВСЕ ТЕСТЫ ПРОЙДЕНЫ! Система работает корректно.")
        else:
            print("НЕКОТОРЫЕ ТЕСТЫ НЕ ПРОЙДЕНЫ! Требуется отладка.")
    
    def _test_basic_commands(self):
        """Тест основных команд"""
        tests = [
            ("Команда help", lambda: self._handle_help() is None),
            ("Команда version", lambda: self._handle_version() is None),
            ("Команда start", lambda: self._handle_start() is None),
            ("Команда open-data", lambda: self._handle_open_data() is None),
        ]
        
        return self._run_test_group(tests)
    
    def _test_file_manager(self):
        """Тест файлового менеджера"""
        if not self.fm:
            print("Файловый менеджер не доступен для тестирования")
            return 0, 0
        
        tests = [
            ("Текущая директория", lambda: self._handle_file_pwd() is None),
            ("Информация о диске", lambda: self._handle_file_disk() is None),
            ("Список файлов", lambda: self._handle_file_list('.', False) is None),
            ("Скриншот", lambda: self._handle_file_screenshot(None) is None),
        ]
        
        return self._run_test_group(tests)
    
    def _test_knowledge_system(self):
        """Тест системы знаний"""
        if not self.km:
            print("Система знаний не доступна для тестирования")
            return 0, 0
        
        tests = [
            ("Статистика знаний", lambda: self._handle_stats() is None),
        ]
        
        return self._run_test_group(tests)
    
    def _run_test_group(self, tests):
        """Запуск группы тестов"""
        passed = 0
        total = len(tests)
        
        for test_name, test_func in tests:
            try:
                test_func()
                print(f"  [OK] {test_name}")
                passed += 1
            except Exception as e:
                print(f"  [FAIL] {test_name}: {e}")
        
        return passed, total
    
    # Справка
    def _show_main_help(self):
        """Показать основную справку"""
        help_text = """
Jarvis AI - Персональный AI ассистент с полным доступом к системе

ОСНОВНЫЕ КОМАНДЫ:
  start              Запуск интерактивного режима с нейросетью
  stats              Показать статистику системы знаний
  search <запрос>    Поиск в базе знаний
  open-data          Открыть папку с данными Jarvis
  analyze <проблема> Анализ проблем на экране (создает скриншот)
  screenshots        Показать последние скриншоты
  file               Операции с файлами (jarvis file help)
  knowledge          Работа со знаниями (jarvis knowledge help)
  version            Показать версию
  test               Запустить тесты системы
  help               Эта справка

ПРИМЕРЫ:
  jarvis start
  jarvis search "программирование Python"
  jarvis analyze "не работает кнопка сохранения"
  jarvis screenshots --limit 3
  jarvis file list
  jarvis file mkdir project
  jarvis file screenshot
  jarvis knowledge import data.txt
  jarvis test

Для подробной справки по конкретной группе команд используйте:
  jarvis file help
  jarvis knowledge help
"""
        print(help_text)
    
    def _show_file_help(self):
        """Показать справку по файловым командам"""
        help_text = """
ФАЙЛОВЫЕ КОМАНДЫ:

  list [path] [--hidden]     Список файлов и директорий
  cd <path>                  Сменить текущую директорию
  mkdir <name> [--path]      Создать новую директорию
  touch <name> [--content] [--path] Создать файл
  rm <path> [-r]            Удалить файл/директорию
  cp <source> <destination> Копировать файл/директорию
  mv <source> <destination> Переместить файл/директорию
  find <pattern> [--dir] [--no-recursive] Поиск файлов
  info <path>               Детальная информация о файле
  disk                      Информация об использовании диска
  pwd                       Текущая рабочая директория
  cat <path>                Показать содержимое файла
  screenshot [--path]       Сделать скриншот
  help                      Показать эту справку

ПРИМЕРЫ:
  jarvis file list
  jarvis file cd /home/user/Documents
  jarvis file mkdir my_project
  jarvis file touch readme.txt --content "# My Project"
  jarvis file find "*.py" --dir /projects
  jarvis file info document.pdf
  jarvis file disk
  jarvis file cat config.txt
  jarvis file screenshot
  jarvis file screenshot --path /path/to/screenshot.png
"""
        print(help_text)
    
    def _show_knowledge_help(self):
        """Показать справку по командам знаний"""
        help_text = """
КОМАНДЫ СИСТЕМЫ ЗНАНИЙ:

  import <file_path>        Импорт данных из файла
  create-topic <name> <content> [--tags] Создать новую тему
  list-topics               Список всех тем в системе
  help                      Показать эту справку

ПРИМЕРЫ:
  jarvis knowledge import data.txt
  jarvis knowledge create-topic "Python" "Язык программирования" --tags programming code
  jarvis knowledge list-topics
"""
        print(help_text)


def main():
    """Точка входа в приложение"""
    try:
        cli = JarvisCLI()
        cli.main()
    except KeyboardInterrupt:
        print("\nДо свидания! Jarvis AI завершает работу.")
    except Exception as e:
        print(f"Критическая ошибка: {e}")
        sys.exit(1)


if __name__ == "__main__":
    main()