"""
Пример 6: Работа с сигналами

Демонстрация привязки сигналов:
- bindSignal() - привязка сигнала к свойству
- Оператор << для обратной привязки
"""

import sys

from PyQt6.QtWidgets import QHBoxLayout
from qtpy.QtWidgets import QApplication, QWidget, QVBoxLayout, QLabel, QPushButton, QSlider
from qtpy.QtCore import Signal
from qtmvvm import ObservableProperty, BaseViewModel


class TimeViewModel(BaseViewModel):
    """ViewModel с временем"""
    hours: int = 12
    minutes: int = 0
    seconds: int = 0
    
    # Сигнал тика (эмулирует таймер)
    tick = Signal()


class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Пример 6: Работа с сигналами")
        
        self.vm = TimeViewModel()
        
        # Метки времени
        self.time_label = QLabel("12:00:00")
        self.time_label.setStyleSheet("font-size: 24px; font-family: monospace;")
        
        # Слайдеры для ручной установки
        self.hours_slider = QSlider()
        # self.hours_slider.setOrientation(1)
        self.hours_slider.setRange(0, 23)
        self.hours_slider.setValue(12)
        
        self.minutes_slider = QSlider()
        # self.minutes_slider.setOrientation(1)
        self.minutes_slider.setRange(0, 59)
        
        self.seconds_slider = QSlider()
        # self.seconds_slider.setOrientation(1)
        self.seconds_slider.setRange(0, 59)
        
        # Кнопки управления
        self.start_btn = QPushButton("Старт")
        self.stop_btn = QPushButton("Стоп")
        self.reset_btn = QPushButton("Сброс")
        
        # Привязка слайдеров (2-way)
        self.vm.get_property("hours") @ self.hours_slider
        self.vm.get_property("minutes") @ self.minutes_slider
        self.vm.get_property("seconds") @ self.seconds_slider
        
        # Привязка свойства к метке (1-way)
        # При изменении любого из свойств времени обновляем метку
        def update_time_label(*args):
            self.time_label.setText(
                f"{self.vm.hours():02d}:{self.vm.minutes():02d}:{self.vm.seconds():02d}"
            )
        
        self.vm.get_property("hours").valueChanged.connect(update_time_label)
        self.vm.get_property("minutes").valueChanged.connect(update_time_label)
        self.vm.get_property("seconds").valueChanged.connect(update_time_label)
        
        # Привязка сигнала tick к свойству seconds
        # При каждом тике увеличиваем секунды
        self.vm.tick.connect(self.on_tick)
        
        # Обработчики кнопок
        self.start_btn.clicked.connect(self.start_timer)
        self.stop_btn.clicked.connect(self.stop_timer)
        self.reset_btn.clicked.connect(self.reset_time)
        
        # Таймер
        self.timer_id = None
        
        # Компоновка
        layout = QVBoxLayout()
        layout.addWidget(self.time_label)
        layout.addWidget(QLabel("Часы:"))
        layout.addWidget(self.hours_slider)
        layout.addWidget(QLabel("Минуты:"))
        layout.addWidget(self.minutes_slider)
        layout.addWidget(QLabel("Секунды:"))
        layout.addWidget(self.seconds_slider)
        
        btn_layout = QHBoxLayout()
        btn_layout.addWidget(self.start_btn)
        btn_layout.addWidget(self.stop_btn)
        btn_layout.addWidget(self.reset_btn)
        layout.addLayout(btn_layout)
        
        self.setLayout(layout)
    
    def on_tick(self):
        """Обработчик тика таймера"""
        self.vm.seconds = (self.vm.seconds + 1) % 60
        if self.vm.seconds == 0:
            self.vm.minutes = (self.vm.minutes + 1) % 60
            if self.vm.minutes == 0:
                self.vm.hours = (self.vm.hours + 1) % 24
    
    def start_timer(self):
        """Запуск таймера"""
        if self.timer_id is None:
            self.timer_id = self.startTimer(1000)  # 1 секунда
    
    def stop_timer(self):
        """Остановка таймера"""
        if self.timer_id is not None:
            self.killTimer(self.timer_id)
            self.timer_id = None
    
    def reset_time(self):
        """Сброс времени"""
        self.vm.hours = 12
        self.vm.minutes = 0
        self.vm.seconds = 0
    
    def timerEvent(self, event):
        """Событие таймера"""
        self.vm.tick.emit()


if __name__ == "__main__":
    app = QApplication(sys.argv)
    main = MainWindow()
    main.show()

    def except_hook(cls, exception, traceback):
        sys.__excepthook__(cls, exception, traceback)

    # Execute the application
    sys.excepthook = except_hook
    sys.exit(app.exec())
