#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
Расширенные обработчики команд для управления Synology NAS
"""

import logging
from datetime import datetime
from typing import List, Dict, Any
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import ContextTypes

from src.config.config import ADMIN_USER_IDS
from src.api.synology import SynologyAPI

logger = logging.getLogger(__name__)

# Инициализация API Synology
synology_api = SynologyAPI()

async def processes_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """Обработчик команды /processes для получения списка активных процессов"""
    user_id = update.effective_user.id
    
    if user_id not in ADMIN_USER_IDS:
        await update.message.reply_text("У вас нет доступа к этому боту.")
        return
        
    message = await update.message.reply_text("⏳ Получение информации о запущенных процессах...")
    
    if not synology_api.is_online():
        await message.edit_text("❌ <b>Synology NAS оффлайн</b>\n\nНевозможно получить информацию о процессах.", parse_mode="HTML")
        return
    
    try:
        processes = synology_api.get_processes(limit=15)  # Получаем топ-15 процессов
        
        if not processes:
            await message.edit_text("❌ <b>Ошибка получения информации о процессах</b>\n\nВозможно, API не поддерживает эту функцию или требуются дополнительные права доступа.", parse_mode="HTML")
            return
    except Exception as e:
        await message.edit_text(f"❌ <b>Ошибка получения информации о процессах</b>\n\nПричина: {str(e)}", parse_mode="HTML")
        return
    
    # Формируем сообщение о процессах
    reply_text = f"⚙️ <b>Активные процессы Synology NAS</b>\n\n"
    
    for process in processes:
        name = process.get("name", "unknown")
        pid = process.get("pid", "?")
        cpu_usage = process.get("cpu_usage", 0)
        memory_usage = process.get("memory_usage", 0)
        
        reply_text += f"• <b>{name}</b> (PID: {pid})\n"
        reply_text += f"  └ CPU: {cpu_usage:.1f}%, Память: {memory_usage:.1f}%\n"
    
    reply_text += f"\n<i>Показано {len(processes)} наиболее активных процессов</i>"
    await message.edit_text(reply_text, parse_mode="HTML")

async def network_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """Обработчик команды /network для получения информации о сетевых подключениях"""
    user_id = update.effective_user.id
    
    if user_id not in ADMIN_USER_IDS:
        await update.message.reply_text("У вас нет доступа к этому боту.")
        return
        
    message = await update.message.reply_text("⏳ Получение информации о сетевых подключениях...")
    
    if not synology_api.is_online():
        await message.edit_text("❌ <b>Synology NAS оффлайн</b>\n\nНевозможно получить информацию о сетевых подключениях.", parse_mode="HTML")
        return
    
    try:
        network_status = synology_api.get_network_status()
        
        if not network_status:
            await message.edit_text("❌ <b>Ошибка получения информации о сетевых подключениях</b>\n\nВозможно, API не поддерживает эту функцию или требуются дополнительные права доступа.", parse_mode="HTML")
            return
    except Exception as e:
        await message.edit_text(f"❌ <b>Ошибка получения информации о сетевых подключениях</b>\n\nПричина: {str(e)}", parse_mode="HTML")
        return
    
    # Формируем сообщение о сетевых интерфейсах
    interfaces = network_status.get("interfaces", [])
    
    reply_text = f"🌐 <b>Сетевые подключения Synology NAS</b>\n\n"
    
    for interface in interfaces:
        name = interface.get("id", "unknown")
        ip = interface.get("ip", "Нет данных")
        mac = interface.get("mac", "Нет данных")
        status = "Активен" if interface.get("status") else "Неактивен"
        
        # Информация о трафике
        rx_bytes = interface.get("rx", 0) / (1024**2)  # Перевод в МБ
        tx_bytes = interface.get("tx", 0) / (1024**2)  # Перевод в МБ
        
        reply_text += f"• <b>{name}</b> ({status})\n"
        reply_text += f"  └ IP: {ip}, MAC: {mac}\n"
        
        if rx_bytes > 0 or tx_bytes > 0:
            reply_text += f"  └ Получено: {rx_bytes:.2f} МБ, Отправлено: {tx_bytes:.2f} МБ\n"
    
    await message.edit_text(reply_text, parse_mode="HTML")

async def temperature_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """Обработчик команды /temperature для мониторинга температуры"""
    user_id = update.effective_user.id
    
    if user_id not in ADMIN_USER_IDS:
        await update.message.reply_text("У вас нет доступа к этому боту.")
        return
        
    message = await update.message.reply_text("⏳ Получение информации о температуре...")
    
    if not synology_api.is_online():
        await message.edit_text("❌ <b>Synology NAS оффлайн</b>\n\nНевозможно получить информацию о температуре.", parse_mode="HTML")
        return
    
    try:
        temp_status = synology_api.get_temperature_status()
        
        if not temp_status:
            await message.edit_text("❌ <b>Ошибка получения информации о температуре</b>\n\nВозможно, API не поддерживает эту функцию или требуются дополнительные права доступа.", parse_mode="HTML")
            return
    except Exception as e:
        await message.edit_text(f"❌ <b>Ошибка получения информации о температуре</b>\n\nПричина: {str(e)}", parse_mode="HTML")
        return
    
    # Формируем сообщение о температуре
    system_temp = temp_status.get("system_temperature")
    disk_temps = temp_status.get("disk_temperatures", [])
    is_warning = temp_status.get("warning", False)
    
    # Выбор emoji в зависимости от температуры
    temp_emoji = "🔥" if is_warning else "🌡️"
    
    reply_text = f"{temp_emoji} <b>Температура Synology NAS</b>\n\n"
    
    if system_temp is not None:
        temp_status_text = "❗ <b>ПОВЫШЕННАЯ</b>" if is_warning else "✅ Нормальная"
        reply_text += f"<b>Температура системы:</b> {system_temp}°C ({temp_status_text})\n\n"
    
    if disk_temps:
        reply_text += "<b>Температура дисков:</b>\n"
        for disk in disk_temps:
            name = disk.get("name", "unknown")
            model = disk.get("model", "unknown")
            temp = disk.get("temperature", 0)
            
            disk_temp_emoji = "🔥" if temp > 45 else "✅"
            reply_text += f"• {disk_temp_emoji} <b>{name}</b> ({model}): {temp}°C\n"
    
    await message.edit_text(reply_text, parse_mode="HTML")

async def schedule_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """Обработчик команды /schedule для управления расписанием питания"""
    user_id = update.effective_user.id
    
    if user_id not in ADMIN_USER_IDS:
        await update.message.reply_text("У вас нет доступа к этому боту.")
        return
        
    message = await update.message.reply_text("⏳ Получение информации о расписании питания...")
    
    if not synology_api.is_online():
        await message.edit_text("❌ <b>Synology NAS оффлайн</b>\n\nНевозможно получить информацию о расписании питания.", parse_mode="HTML")
        return
    
    try:
        schedule = synology_api.get_power_schedule()
        
        if not schedule:
            await message.edit_text("❌ <b>Ошибка получения информации о расписании питания</b>\n\nВозможно, API не поддерживает эту функцию или требуются дополнительные права доступа.", parse_mode="HTML")
            return
    except Exception as e:
        await message.edit_text(f"❌ <b>Ошибка получения информации о расписании питания</b>\n\nПричина: {str(e)}", parse_mode="HTML")
        return
    
    # Формируем сообщение о расписании питания
    boot_tasks = schedule.get("boot_tasks", [])
    shutdown_tasks = schedule.get("shutdown_tasks", [])
    
    reply_text = f"⏱️ <b>Расписание питания Synology NAS</b>\n\n"
    
    if boot_tasks:
        reply_text += "<b>Расписание включения:</b>\n"
        for task in boot_tasks:
            days = task.get("day", [])
            time = task.get("time", "00:00")
            enabled = task.get("enabled", False)
            
            # Преобразуем номера дней в названия
            day_names = []
            for day in days:
                if day == 0: day_names.append("Пн")
                elif day == 1: day_names.append("Вт")
                elif day == 2: day_names.append("Ср")
                elif day == 3: day_names.append("Чт")
                elif day == 4: day_names.append("Пт")
                elif day == 5: day_names.append("Сб")
                elif day == 6: day_names.append("Вс")
            
            status = "✅ Активно" if enabled else "❌ Отключено"
            day_str = ", ".join(day_names) if day_names else "Нет дней"
            
            reply_text += f"• {status}: {time} ({day_str})\n"
    else:
        reply_text += "<b>Расписание включения:</b> Не настроено\n"
    
    reply_text += "\n"
    
    if shutdown_tasks:
        reply_text += "<b>Расписание выключения:</b>\n"
        for task in shutdown_tasks:
            days = task.get("day", [])
            time = task.get("time", "00:00")
            enabled = task.get("enabled", False)
            
            # Преобразуем номера дней в названия
            day_names = []
            for day in days:
                if day == 0: day_names.append("Пн")
                elif day == 1: day_names.append("Вт")
                elif day == 2: day_names.append("Ср")
                elif day == 3: day_names.append("Чт")
                elif day == 4: day_names.append("Пт")
                elif day == 5: day_names.append("Сб")
                elif day == 6: day_names.append("Вс")
            
            status = "✅ Активно" if enabled else "❌ Отключено"
            day_str = ", ".join(day_names) if day_names else "Нет дней"
            
            reply_text += f"• {status}: {time} ({day_str})\n"
    else:
        reply_text += "<b>Расписание выключения:</b> Не настроено\n"
    
    # Добавляем кнопки для управления расписанием
    keyboard = [
        [
            InlineKeyboardButton("➕ Добавить включение", callback_data="schedule_add_boot"),
            InlineKeyboardButton("➕ Добавить выключение", callback_data="schedule_add_shutdown")
        ],
        [
            InlineKeyboardButton("🗑️ Удалить расписание", callback_data="schedule_delete")
        ]
    ]
    reply_markup = InlineKeyboardMarkup(keyboard)
    
    await message.edit_text(reply_text, parse_mode="HTML", reply_markup=reply_markup)

async def browse_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """Обработчик команды /browse для просмотра файлов"""
    user_id = update.effective_user.id
    
    if user_id not in ADMIN_USER_IDS:
        await update.message.reply_text("У вас нет доступа к этому боту.")
        return
    
    # Получаем путь из аргументов команды или используем корневую директорию
    path = " ".join(context.args) if context.args else ""
    
    message = await update.message.reply_text(f"⏳ Получение содержимого {'папки ' + path if path else 'общих папок'}...")
    
    if not synology_api.is_online():
        await message.edit_text("❌ <b>Synology NAS оффлайн</b>\n\nНевозможно получить список файлов.", parse_mode="HTML")
        return
    
    try:
        browse_result = synology_api.browse_files(folder_path=path)
        
        if not browse_result.get("success", False):
            error = browse_result.get("error", "unknown")
            await message.edit_text(f"❌ <b>Ошибка получения списка файлов</b>\n\nПричина: {error}", parse_mode="HTML")
            return
            
        items = browse_result.get("items", [])
        current_path = browse_result.get("path", "")
        is_root = browse_result.get("is_root", True)
        
    except Exception as e:
        await message.edit_text(f"❌ <b>Ошибка получения списка файлов</b>\n\nПричина: {str(e)}", parse_mode="HTML")
        return
    
    # Формируем сообщение о файлах и папках
    if is_root:
        reply_text = f"📁 <b>Общие папки Synology NAS</b>\n\n"
    else:
        reply_text = f"📁 <b>Содержимое папки</b>\n<code>{current_path}</code>\n\n"
    
    # Сортируем: сначала папки, потом файлы
    folders = []
    files = []
    
    for item in items:
        if is_root:  # Для корневого уровня все элементы - это общие папки
            name = item.get("name", "unknown")
            path = item.get("path", "")
            folders.append((name, path, True))
        else:
            name = item.get("name", "unknown")
            path = item.get("path", "")
            is_dir = item.get("isdir", False)
            
            if is_dir:
                folders.append((name, path, False))
            else:
                # Для файлов получаем размер
                size = item.get("additional", {}).get("size", 0)
                size_str = format_size(size)
                files.append((name, path, size_str))
    
    # Добавляем папки в сообщение
    if folders:
        for name, path, is_share in folders:
            # Для общих папок добавляем иконку дома
            icon = "🏠" if is_share else "📁"
            reply_text += f"{icon} <a href=\"tg://browse?path={path}\">{name}</a>\n"
    
    # Добавляем файлы в сообщение
    if files:
        for name, path, size in files:
            # Выбираем иконку в зависимости от расширения
            icon = get_file_icon(name)
            reply_text += f"{icon} {name} ({size})\n"
    
    # Если нет элементов для отображения
    if not folders and not files:
        reply_text += "📭 <i>Папка пуста</i>\n"
    
    # Добавляем кнопку возврата наверх, если мы не в корне
    if not is_root:
        # Определяем родительскую директорию
        parent_path = "/".join(current_path.split("/")[:-1]) if "/" in current_path else ""
        
        keyboard = [
            [InlineKeyboardButton("🔼 Вернуться на уровень выше", callback_data=f"browse_{parent_path}")]
        ]
        reply_markup = InlineKeyboardMarkup(keyboard)
        
        await message.edit_text(reply_text, parse_mode="HTML", reply_markup=reply_markup)
    else:
        await message.edit_text(reply_text, parse_mode="HTML")

async def search_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """Обработчик команды /search для поиска файлов"""
    user_id = update.effective_user.id
    
    if user_id not in ADMIN_USER_IDS:
        await update.message.reply_text("У вас нет доступа к этому боту.")
        return
    
    # Получаем шаблон поиска из аргументов команды
    if not context.args:
        await update.message.reply_text("❌ Укажите шаблон для поиска: /search <шаблон>")
        return
        
    pattern = " ".join(context.args)
    
    message = await update.message.reply_text(f"⏳ Поиск файлов по шаблону «{pattern}»...")
    
    if not synology_api.is_online():
        await message.edit_text("❌ <b>Synology NAS оффлайн</b>\n\nНевозможно выполнить поиск файлов.", parse_mode="HTML")
        return
    
    try:
        search_result = synology_api.search_files(pattern=pattern, limit=20)
        
        if not search_result.get("success", False):
            error = search_result.get("error", "unknown")
            progress = search_result.get("progress", 0)
            
            if error == "search_timeout":
                await message.edit_text(f"❌ <b>Превышено время ожидания результатов поиска</b>\n\nПроцесс поиска выполнен на {progress}%", parse_mode="HTML")
            else:
                await message.edit_text(f"❌ <b>Ошибка при поиске файлов</b>\n\nПричина: {error}", parse_mode="HTML")
            return
            
        files = search_result.get("results", [])
        total = search_result.get("total", len(files))
        
    except Exception as e:
        await message.edit_text(f"❌ <b>Ошибка при поиске файлов</b>\n\nПричина: {str(e)}", parse_mode="HTML")
        return
    
    # Формируем сообщение с результатами поиска
    reply_text = f"🔍 <b>Результаты поиска по шаблону «{pattern}»</b>\n\n"
    
    if not files:
        reply_text += "📭 <i>Файлы не найдены</i>"
    else:
        # Сортируем: сначала папки, потом файлы
        folders = []
        found_files = []
        
        for item in files:
            name = item.get("name", "unknown")
            path = item.get("path", "")
            is_dir = item.get("isdir", False)
            
            if is_dir:
                folders.append((name, path))
            else:
                # Для файлов получаем размер и путь к родительской папке
                size = item.get("additional", {}).get("size", 0)
                size_str = format_size(size)
                parent_path = "/".join(path.split("/")[:-1])
                found_files.append((name, path, size_str, parent_path))
        
        # Добавляем папки в сообщение
        if folders:
            reply_text += "<b>Найденные папки:</b>\n"
            for name, path in folders[:5]:  # Показываем первые 5 папок
                reply_text += f"📁 <a href=\"tg://browse?path={path}\">{name}</a>\n"
            
            if len(folders) > 5:
                reply_text += f"<i>...и еще {len(folders) - 5} папок</i>\n"
                
            reply_text += "\n"
        
        # Добавляем файлы в сообщение
        if found_files:
            reply_text += "<b>Найденные файлы:</b>\n"
            for name, path, size, parent in found_files[:10]:  # Показываем первые 10 файлов
                icon = get_file_icon(name)
                reply_text += f"{icon} {name} ({size})\n"
                reply_text += f"   <i>Путь: .../{path.split('/')[-2]}/</i>\n"
            
            if len(found_files) > 10:
                reply_text += f"<i>...и еще {len(found_files) - 10} файлов</i>\n"
        
        # Добавляем информацию о общем количестве результатов
        reply_text += f"\n<i>Всего найдено: {total} элементов</i>"
    
    await message.edit_text(reply_text, parse_mode="HTML")

async def updates_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """Обработчик команды /updates для проверки обновлений"""
    user_id = update.effective_user.id
    
    if user_id not in ADMIN_USER_IDS:
        await update.message.reply_text("У вас нет доступа к этому боту.")
        return
        
    message = await update.message.reply_text("⏳ Проверка доступных обновлений...")
    
    if not synology_api.is_online():
        await message.edit_text("❌ <b>Synology NAS оффлайн</b>\n\nНевозможно проверить наличие обновлений.", parse_mode="HTML")
        return
    
    try:
        update_info = synology_api.check_for_updates()
        
        if not update_info.get("success", False):
            error = update_info.get("error", "unknown")
            await message.edit_text(f"❌ <b>Ошибка при проверке обновлений</b>\n\nПричина: {error}", parse_mode="HTML")
            return
            
        current_version = update_info.get("current_version", "unknown")
        update_available = update_info.get("update_available", False)
        auto_update = update_info.get("auto_update_enabled", False)
        updates = update_info.get("updates", [])
        
    except Exception as e:
        await message.edit_text(f"❌ <b>Ошибка при проверке обновлений</b>\n\nПричина: {str(e)}", parse_mode="HTML")
        return
    
    # Формируем сообщение об обновлениях
    if update_available:
        reply_text = f"🔄 <b>Доступны обновления DSM</b>\n\n"
        reply_text += f"<b>Текущая версия:</b> {current_version}\n"
        reply_text += f"<b>Автообновление:</b> {'✅ Включено' if auto_update else '❌ Отключено'}\n\n"
        reply_text += "<b>Доступные обновления:</b>\n"
        
        for update_item in updates:
            update_name = update_item.get("name", "unknown")
            update_version = update_item.get("version", "unknown")
            update_size = update_item.get("size", 0)
            update_size_str = format_size(update_size)
            
            reply_text += f"• <b>{update_name}</b> v{update_version}\n"
            reply_text += f"  └ Размер: {update_size_str}\n"
    else:
        reply_text = f"✅ <b>Система в актуальном состоянии</b>\n\n"
        reply_text += f"<b>Текущая версия:</b> {current_version}\n"
        reply_text += f"<b>Автообновление:</b> {'✅ Включено' if auto_update else '❌ Отключено'}\n"
    
    await message.edit_text(reply_text, parse_mode="HTML")

async def backup_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """Обработчик команды /backup для управления резервным копированием"""
    user_id = update.effective_user.id
    
    if user_id not in ADMIN_USER_IDS:
        await update.message.reply_text("У вас нет доступа к этому боту.")
        return
        
    message = await update.message.reply_text("⏳ Получение информации о резервном копировании...")
    
    if not synology_api.is_online():
        await message.edit_text("❌ <b>Synology NAS оффлайн</b>\n\nНевозможно получить информацию о резервном копировании.", parse_mode="HTML")
        return
    
    try:
        backup_status = synology_api.get_backup_status()
        
        if not backup_status.get("success", False):
            error = backup_status.get("error", "unknown")
            await message.edit_text(f"❌ <b>Ошибка получения информации о резервном копировании</b>\n\nПричина: {error}", parse_mode="HTML")
            return
            
        backups = backup_status.get("backups", {})
        api_status = backup_status.get("available_apis", {})
        
    except Exception as e:
        await message.edit_text(f"❌ <b>Ошибка получения информации о резервном копировании</b>\n\nПричина: {str(e)}", parse_mode="HTML")
        return
    
    # Формируем сообщение о резервном копировании
    reply_text = f"💾 <b>Резервное копирование Synology NAS</b>\n\n"
    
    # Информация о Hyper Backup
    hyper_backups = backups.get("hyper_backup", [])
    hyper_api_available = api_status.get("hyper_backup", False)
    
    if hyper_api_available:
        reply_text += "<b>Hyper Backup:</b>\n"
        
        if hyper_backups:
            for backup in hyper_backups:
                name = backup.get("name", "unknown")
                status = backup.get("status", "unknown")
                last_backup = backup.get("last_backup", "never")
                
                status_emoji = "✅" if status.lower() == "success" else "⚠️"
                reply_text += f"• {status_emoji} <b>{name}</b>\n"
                reply_text += f"  └ Последнее копирование: {last_backup}\n"
        else:
            reply_text += "<i>Задачи Hyper Backup не настроены</i>\n"
        
        reply_text += "\n"
    
    # Информация о Time Backup
    time_backups = backups.get("time_backup", [])
    time_api_available = api_status.get("time_backup", False)
    
    if time_api_available:
        reply_text += "<b>Time Backup:</b>\n"
        
        if time_backups:
            for backup in time_backups:
                name = backup.get("name", "unknown")
                status = backup.get("status", "unknown")
                
                status_emoji = "✅" if status.lower() == "normal" else "⚠️"
                reply_text += f"• {status_emoji} <b>{name}</b>\n"
        else:
            reply_text += "<i>Задачи Time Backup не настроены</i>\n"
        
        reply_text += "\n"
    
    # Информация о USB Copy
    usb_copy = backups.get("usb_copy", {})
    usb_api_available = api_status.get("usb_copy", False)
    
    if usb_api_available:
        usb_enabled = usb_copy.get("enabled", False)
        usb_status = "✅ Включено" if usb_enabled else "❌ Отключено"
        
        reply_text += f"<b>USB Copy:</b> {usb_status}\n\n"
    
    # Если ни один из API не доступен
    if not any(api_status.values()):
        reply_text += "<i>API для резервного копирования не доступны на вашем NAS или требуют дополнительных прав доступа.</i>\n"
    
    await message.edit_text(reply_text, parse_mode="HTML")

async def reboot_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """Обработчик команды /reboot для перезагрузки NAS"""
    user_id = update.effective_user.id
    
    if user_id not in ADMIN_USER_IDS:
        await update.message.reply_text("У вас нет доступа к этому боту.")
        return
    
    # Добавляем подтверждение перед перезагрузкой
    keyboard = [
        [
            InlineKeyboardButton("✅ Да, перезагрузить", callback_data="confirm_reboot"),
            InlineKeyboardButton("❌ Отмена", callback_data="cancel_reboot")
        ]
    ]
    reply_markup = InlineKeyboardMarkup(keyboard)
    
    await update.message.reply_text(
        "⚠️ <b>Вы уверены, что хотите перезагрузить Synology NAS?</b>\n\n"
        "Это действие может привести к прерыванию работы всех сервисов.",
        parse_mode="HTML",
        reply_markup=reply_markup
    )

async def sleep_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """Обработчик команды /sleep для перевода NAS в спящий режим"""
    user_id = update.effective_user.id
    
    if user_id not in ADMIN_USER_IDS:
        await update.message.reply_text("У вас нет доступа к этому боту.")
        return
    
    # Добавляем подтверждение перед отправкой в спящий режим
    keyboard = [
        [
            InlineKeyboardButton("✅ Да, усыпить", callback_data="confirm_sleep"),
            InlineKeyboardButton("❌ Отмена", callback_data="cancel_sleep")
        ]
    ]
    reply_markup = InlineKeyboardMarkup(keyboard)
    
    await update.message.reply_text(
        "⚠️ <b>Вы уверены, что хотите перевести Synology NAS в спящий режим?</b>\n\n"
        "Это действие приведет к остановке всех сервисов и отключению NAS.",
        parse_mode="HTML",
        reply_markup=reply_markup
    )

async def quickreboot_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """Обработчик команды /quickreboot для быстрой перезагрузки NAS"""
    user_id = update.effective_user.id
    
    if user_id not in ADMIN_USER_IDS:
        await update.message.reply_text("У вас нет доступа к этому боту.")
        return
        
    message = await update.message.reply_text("⏳ Выполняется перезагрузка Synology NAS...")
    
    if not synology_api.is_online():
        await message.edit_text("❌ <b>Synology NAS оффлайн</b>\n\nНевозможно выполнить перезагрузку.", parse_mode="HTML")
        return
    
    try:
        # Выполняем перезагрузку
        result = synology_api.reboot_system()
        
        if result:
            # Формируем сообщение об успешной перезагрузке
            reply_text = "🔄 <b>Synology NAS перезагружается</b>\n\n"
            reply_text += "<i>Перезагрузка обычно занимает 3-5 минут. После перезагрузки NAS будет снова доступен.</i>"
            await message.edit_text(reply_text, parse_mode="HTML")
        else:
            await message.edit_text("❌ <b>Ошибка при выполнении перезагрузки</b>\n\nПроверьте журналы NAS для получения дополнительной информации.", parse_mode="HTML")
            
    except Exception as e:
        await message.edit_text(f"❌ <b>Ошибка при выполнении перезагрузки</b>\n\nПричина: {str(e)}", parse_mode="HTML")
        return

async def wakeup_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """Обработчик команды /wakeup для включения NAS"""
    user_id = update.effective_user.id
    
    if user_id not in ADMIN_USER_IDS:
        await update.message.reply_text("У вас нет доступа к этому боту.")
        return
        
    message = await update.message.reply_text("⏳ Отправка пакета Wake-on-LAN для включения Synology NAS...")
    
    # Проверяем, не включен ли NAS уже
    if synology_api.is_online(force_check=True):
        await message.edit_text("ℹ️ <b>Synology NAS уже включен</b>\n\nНет необходимости отправлять сигнал пробуждения.", parse_mode="HTML")
        return
    
    try:
        # Отправляем сигнал пробуждения
        result = synology_api.power_on()
        
        if result:
            # Формируем сообщение об успешном включении
            reply_text = "✅ <b>Synology NAS успешно включен</b>\n\n"
            reply_text += "<i>NAS полностью готов к работе.</i>"
            await message.edit_text(reply_text, parse_mode="HTML")
        else:
            await message.edit_text("❌ <b>Ошибка при включении NAS</b>\n\nВозможные причины:\n- Функция Wake-on-LAN не настроена на NAS\n- Неверно указан MAC-адрес\n- Проблемы с сетевым подключением", parse_mode="HTML")
            
    except Exception as e:
        await message.edit_text(f"❌ <b>Ошибка при включении NAS</b>\n\nПричина: {str(e)}", parse_mode="HTML")
        return

async def quota_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """Обработчик команды /quota для просмотра информации о квотах"""
    user_id = update.effective_user.id
    
    if user_id not in ADMIN_USER_IDS:
        await update.message.reply_text("У вас нет доступа к этому боту.")
        return
        
    message = await update.message.reply_text("⏳ Получение информации о квотах пользователей...")
    
    if not synology_api.is_online():
        await message.edit_text("❌ <b>Synology NAS оффлайн</b>\n\nНевозможно получить информацию о квотах.", parse_mode="HTML")
        return
    
    try:
        quota_info = synology_api.get_quota_info()
        
        if not quota_info.get("success", False):
            error = quota_info.get("error", "unknown")
            await message.edit_text(f"❌ <b>Ошибка получения информации о квотах</b>\n\nПричина: {error}", parse_mode="HTML")
            return
            
        user_quotas = quota_info.get("user_quotas", [])
        
    except Exception as e:
        await message.edit_text(f"❌ <b>Ошибка получения информации о квотах</b>\n\nПричина: {str(e)}", parse_mode="HTML")
        return
    
    # Формируем сообщение о квотах
    reply_text = f"📊 <b>Квоты пользователей Synology NAS</b>\n\n"
    
    if not user_quotas:
        reply_text += "<i>Квоты пользователей не настроены или недоступны</i>"
    else:
        for user_quota in user_quotas:
            user = user_quota.get("user", "unknown")
            quotas = user_quota.get("quotas", [])
            
            if quotas:
                reply_text += f"<b>Пользователь {user}:</b>\n"
                
                for quota in quotas:
                    volume = quota.get("volume_name", "unknown")
                    limit = quota.get("limit", 0)
                    used = quota.get("used", 0)
                    
                    # Переводим байты в ГБ
                    limit_gb = limit / (1024**3) if limit > 0 else 0
                    used_gb = used / (1024**3)
                    
                    # Рассчитываем процент использования
                    if limit_gb > 0:
                        usage_percent = (used_gb / limit_gb) * 100
                        reply_text += f"• Том {volume}: {used_gb:.2f} ГБ из {limit_gb:.2f} ГБ ({usage_percent:.1f}%)\n"
                    else:
                        reply_text += f"• Том {volume}: {used_gb:.2f} ГБ (без ограничений)\n"
                
                reply_text += "\n"
    
    await message.edit_text(reply_text, parse_mode="HTML")

async def schedule_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """Обработчик callback-запросов для управления расписанием питания"""
    query = update.callback_query
    await query.answer()
    
    user_id = update.effective_user.id
    if user_id not in ADMIN_USER_IDS:
        await query.edit_message_text("У вас нет доступа к этому боту.")
        return
    
    action = query.data
    
    if action.startswith("schedule_"):
        action_type = action.split("_")[1]
        
        if action_type == "add_boot":
            # Логика добавления расписания включения
            # В реальном боте здесь будет диалог для настройки расписания
            await query.edit_message_text("⚙️ <b>Добавление расписания включения</b>\n\n<i>Эта функция находится в разработке.</i>", parse_mode="HTML")
            
        elif action_type == "add_shutdown":
            # Логика добавления расписания выключения
            await query.edit_message_text("⚙️ <b>Добавление расписания выключения</b>\n\n<i>Эта функция находится в разработке.</i>", parse_mode="HTML")
            
        elif action_type == "delete":
            # Логика удаления расписания
            await query.edit_message_text("⚙️ <b>Удаление расписания</b>\n\n<i>Эта функция находится в разработке.</i>", parse_mode="HTML")

async def browse_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """Обработчик callback-запросов для навигации по файловой системе"""
    query = update.callback_query
    await query.answer()
    
    user_id = update.effective_user.id
    if user_id not in ADMIN_USER_IDS:
        await query.edit_message_text("У вас нет доступа к этому боту.")
        return
    
    action = query.data
    
    if action.startswith("browse_"):
        path = action[7:]  # Убираем префикс "browse_"
        
        # Используем команду browse с указанным путем
        message = await query.edit_message_text(f"⏳ Получение содержимого {'папки ' + path if path else 'общих папок'}...")
        
        if not synology_api.is_online():
            await message.edit_text("❌ <b>Synology NAS оффлайн</b>\n\nНевозможно получить список файлов.", parse_mode="HTML")
            return
        
        try:
            browse_result = synology_api.browse_files(folder_path=path)
            
            if not browse_result.get("success", False):
                error = browse_result.get("error", "unknown")
                await message.edit_text(f"❌ <b>Ошибка получения списка файлов</b>\n\nПричина: {error}", parse_mode="HTML")
                return
                
            items = browse_result.get("items", [])
            current_path = browse_result.get("path", "")
            is_root = browse_result.get("is_root", True)
            
        except Exception as e:
            await message.edit_text(f"❌ <b>Ошибка получения списка файлов</b>\n\nПричина: {str(e)}", parse_mode="HTML")
            return
        
        # Формируем сообщение о файлах и папках (аналогично функции browse_command)
        if is_root:
            reply_text = f"📁 <b>Общие папки Synology NAS</b>\n\n"
        else:
            reply_text = f"📁 <b>Содержимое папки</b>\n<code>{current_path}</code>\n\n"
        
        # Сортируем: сначала папки, потом файлы
        folders = []
        files = []
        
        for item in items:
            if is_root:  # Для корневого уровня все элементы - это общие папки
                name = item.get("name", "unknown")
                path = item.get("path", "")
                folders.append((name, path, True))
            else:
                name = item.get("name", "unknown")
                path = item.get("path", "")
                is_dir = item.get("isdir", False)
                
                if is_dir:
                    folders.append((name, path, False))
                else:
                    # Для файлов получаем размер
                    size = item.get("additional", {}).get("size", 0)
                    size_str = format_size(size)
                    files.append((name, path, size_str))
        
        # Добавляем папки в сообщение
        if folders:
            for name, path, is_share in folders:
                # Для общих папок добавляем иконку дома
                icon = "🏠" if is_share else "📁"
                reply_text += f"{icon} <a href=\"tg://browse?path={path}\">{name}</a>\n"
        
        # Добавляем файлы в сообщение
        if files:
            for name, path, size in files:
                # Выбираем иконку в зависимости от расширения
                icon = get_file_icon(name)
                reply_text += f"{icon} {name} ({size})\n"
        
        # Если нет элементов для отображения
        if not folders and not files:
            reply_text += "📭 <i>Папка пуста</i>\n"
        
        # Добавляем кнопку возврата наверх, если мы не в корне
        if not is_root:
            # Определяем родительскую директорию
            parent_path = "/".join(current_path.split("/")[:-1]) if "/" in current_path else ""
            
            keyboard = [
                [InlineKeyboardButton("🔼 Вернуться на уровень выше", callback_data=f"browse_{parent_path}")]
            ]
            reply_markup = InlineKeyboardMarkup(keyboard)
            
            await message.edit_text(reply_text, parse_mode="HTML", reply_markup=reply_markup)
        else:
            await message.edit_text(reply_text, parse_mode="HTML")

# Вспомогательные функции

def format_size(size_bytes: int) -> str:
    """Преобразует размер в байтах в человекочитаемый формат"""
    if size_bytes < 1024:
        return f"{size_bytes} Б"
    elif size_bytes < 1024**2:
        return f"{size_bytes/1024:.1f} КБ"
    elif size_bytes < 1024**3:
        return f"{size_bytes/1024**2:.1f} МБ"
    else:
        return f"{size_bytes/1024**3:.1f} ГБ"

def get_file_icon(filename: str) -> str:
    """Возвращает эмодзи-иконку в зависимости от типа файла"""
    extension = filename.lower().split('.')[-1] if '.' in filename else ''
    
    if extension in ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'tiff', 'webp']:
        return "🖼️"
    elif extension in ['mp4', 'avi', 'mov', 'mkv', 'wmv', 'flv']:
        return "🎬"
    elif extension in ['mp3', 'wav', 'ogg', 'flac', 'aac']:
        return "🎵"
    elif extension in ['doc', 'docx', 'txt', 'rtf', 'odt']:
        return "📄"
    elif extension in ['xls', 'xlsx', 'csv']:
        return "📊"
    elif extension in ['ppt', 'pptx']:
        return "📑"
    elif extension in ['pdf']:
        return "📕"
    elif extension in ['zip', 'rar', '7z', 'tar', 'gz']:
        return "🗜️"
    elif extension in ['exe', 'msi']:
        return "⚙️"
    else:
        return "📄"
