#!/usr/bin/env python3
"""
Системный трей для управления службой zapret
Показывает текущий статус и позволяет управлять службой через меню

Author: MiniMax Agent
"""

import sys
import subprocess
import threading
import os
from pathlib import Path

try:
    from pystray import MenuItem as item
    from pystray import Icon as icon
    from PIL import Image, ImageDraw
    INSTALLED = True
except ImportError:
    INSTALLED = False
    print("Предупреждение: pystray не установлен. Установите: pip install pystray pillow")


# Конфигурация
SERVICE_NAME = "zapret"

# Команды systemctl
STATUS_CMD = f"systemctl is-active {SERVICE_NAME}"
START_CMD = f"sudo systemctl start {SERVICE_NAME}"
STOP_CMD = f"sudo systemctl stop {SERVICE_NAME}"
ENABLE_CMD = f"sudo systemctl enable {SERVICE_NAME}"
DISABLE_CMD = f"sudo systemctl disable {SERVICE_NAME}"
RESTART_CMD = f"sudo systemctl restart {SERVICE_NAME}"
STATUS_DETAIL_CMD = f"systemctl status {SERVICE_NAME}"


def run_command(cmd, need_password=False):
    """Выполняет команду и возвращает результат"""
    try:
        result = subprocess.run(
            cmd,
            shell=True,
            capture_output=True,
            text=True,
            timeout=10
        )
        return result.returncode == 0, result.stdout.strip(), result.stderr.strip()
    except subprocess.TimeoutExpired:
        return False, "", "Таймаут выполнения"
    except Exception as e:
        return False, "", str(e)


def get_service_status():
    """Проверяет статус службы"""
    success, stdout, stderr = run_command(STATUS_CMD)
    if success and "active" in stdout.lower():
        return True  # ON
    return False  # OFF


def get_status_text():
    """Возвращает текст статуса для отображения"""
    if get_service_status():
        return "Zapret: ВКЛ"
    return "Zapret: ВЫКЛ"


def get_status_icon():
    """Возвращает цвета для иконки в зависимости от статуса"""
    if get_service_status():
        return (0, 180, 0)  # Зеленый - включено
    return (200, 0, 0)  # Красный - выключено


def create_icon_image():
    """Создает изображение иконки"""
    # Размер иконки
    size = 64
    image = Image.new('RGB', (size, size), color=(0, 0, 0))
    draw = ImageDraw.Draw(image)
    
    # Получаем цвет в зависимости от статуса
    r, g, b = get_status_icon()
    
    # Рисуем круг
    margin = 8
    draw.ellipse(
        [margin, margin, size - margin, size - margin],
        fill=(r, g, b),
        outline=(255, 255, 255),
        width=3
    )
    
    # Рисуем букву "Z" в центре
    from PIL import ImageFont
    try:
        font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 32)
    except:
        try:
            font = ImageFont.truetype("/usr/share/fonts/truetype/freefont/FreeSansBold.ttf", 32)
        except:
            font = ImageFont.load_default()
    
    # Центрируем текст
    text = "Z"
    bbox = draw.textbbox((0, 0), text, font=font)
    text_width = bbox[2] - bbox[0]
    text_height = bbox[3] - bbox[1]
    x = (size - text_width) // 2
    y = (size - text_height) // 2
    
    draw.text((x, y), text, fill=(255, 255, 255), font=font)
    
    return image


def refresh_icon(icon_obj):
    """Обновляет иконку"""
    try:
        icon_obj.icon = create_icon_image()
        icon_obj.update_menu()
    except Exception as e:
        print(f"Ошибка обновления иконки: {e}")


def action_start(icon_obj, item):
    """Запуск службы"""
    def run():
        success, _, stderr = run_command(START_CMD, need_password=True)
        if success:
            icon_obj.notify("Zapret запущен", "Успех")
            refresh_icon(icon_obj)
        else:
            icon_obj.notify(f"Ошибка: {stderr}", "Ошибка")
    
    threading.Thread(target=run, daemon=True).start()


def action_stop(icon_obj, item):
    """Остановка службы"""
    def run():
        success, _, stderr = run_command(STOP_CMD, need_password=True)
        if success:
            icon_obj.notify("Zapret остановлен", "Успех")
            refresh_icon(icon_obj)
        else:
            icon_obj.notify(f"Ошибка: {stderr}", "Ошибка")
    
    threading.Thread(target=run, daemon=True).start()


def action_toggle(icon_obj, item):
    """Переключение состояния"""
    current_status = get_service_status()
    
    if current_status:
        action_stop(icon_obj, item)
    else:
        action_start(icon_obj, item)


def action_restart(icon_obj, item):
    """Перезапуск службы"""
    def run():
        success, _, stderr = run_command(RESTART_CMD, need_password=True)
        if success:
            icon_obj.notify("Zapret перезапущен", "Успех")
            refresh_icon(icon_obj)
        else:
            icon.notify(f"Ошибка: {stderr}", "Ошибка")
    
    threading.Thread(target=run, daemon=True).start()


def action_enable(icon_obj, item):
    """Включение автозапуска"""
    def run():
        success, _, stderr = run_command(ENABLE_CMD, need_password=True)
        if success:
            icon_obj.notify("Автозапуск включен", "Успех")
        else:
            icon_obj.notify(f"Ошибка: {stderr}", "Ошибка")
    
    threading.Thread(target=run, daemon=True).start()


def action_disable(icon_obj, item):
    """Отключение автозапуска"""
    def run():
        success, _, stderr = run_command(DISABLE_CMD, need_password=True)
        if success:
            icon_obj.notify("Автозапуск отключен", "Успех")
        else:
            icon_obj.notify(f"Ошибка: {stderr}", "Ошибка")
    
    threading.Thread(target=run, daemon=True).start()


def action_status(icon_obj, item):
    """Показать детальный статус"""
    def run():
        success, stdout, stderr = run_command(STATUS_DETAIL_CMD)
        if success:
            icon_obj.notify(stdout[:500], "Статус службы")
        else:
            icon_obj.notify(f"Ошибка получения статуса: {stderr}", "Ошибка")
    
    threading.Thread(target=run, daemon=True).start()


def action_refresh(icon_obj, item):
    """Обновить иконку и статус"""
    refresh_icon(icon_obj)
    icon_obj.notify(get_status_text(), "Статус обновлен")


def action_exit(icon_obj, item):
    """Выход из приложения"""
    icon_obj.stop()


def create_menu():
    """Создает меню для трея"""
    return (
        item('Обновить', action_refresh),
        item('Запустить', action_start),
        item('Остановить', action_stop),
        item('Перезапустить', action_restart),
        item('Включить автозапуск', action_enable),
        item('Отключить автозапуск', action_disable),
        item('Статус', action_status),
        item('Выход', action_exit),
    )


def check_dependencies():
    """Проверяет наличие необходимых зависимостей"""
    # Проверка pystray
    if not INSTALLED:
        print("Ошибка: pystray не установлен")
        print("Установите зависимости:")
        print("  pip install pystray pillow")
        return False
    
    # Проверка systemd (только для Linux)
    if sys.platform != 'linux':
        print("Предупреждение: Это приложение предназначено для Linux с systemd")
    
    # Проверка прав на выполнение systemctl
    success, _, _ = run_command("which systemctl")
    if not success:
        print("Ошибка: systemctl не найден. Убедитесь, что у вас установлен systemd")
        return False
    
    return True


def main():
    """Основная функция"""
    print("Запуск Zapret Tray...")
    
    # Проверка зависимостей
    if not check_dependencies():
        sys.exit(1)
    
    # Создаем иконку
    icon_image = create_icon_image()
    icon_name = "Zapret Control"
    menu = create_menu()
    
    # Создаем иконку трея
    tray_icon = icon(
        icon_name,
        icon_image,
        icon_name,
        menu
    )
    
    # Устанавливаем заголовок с текущим статусом
    tray_icon.title = get_status_text()
    
    print(f"Иконка запущена: {icon_name}")
    print(f"Текущий статус: {get_status_text()}")
    print("Используйте меню в трее для управления службой")
    
    try:
        tray_icon.run()
    except KeyboardInterrupt:
        print("\nЗавершение работы...")
    except Exception as e:
        print(f"Ошибка: {e}")
        sys.exit(1)


if __name__ == "__main__":
    main()
