"""
Пример 3: Вычисляемые свойства (ComputedProperty)

Демонстрация использования @computed_property:
- Автоматическое обновление при изменении зависимостей
- Read-only свойства
- Реактивная архитектура
"""

import sys
from qtpy.QtWidgets import QApplication, QWidget, QVBoxLayout, QLabel, QLineEdit, QDoubleSpinBox
from qtmvvm import BaseViewModel, computed_property


class CalculatorViewModel(BaseViewModel):
    """ViewModel для калькулятора"""
    price: float = 100.0
    quantity: int = 1
    discount: float = 0.0
    
    @computed_property(depends_on=["price", "quantity", "discount"])
    def subtotal(self) -> float:
        """Стоимость без скидки"""
        return self.price * self.quantity
    
    @computed_property(depends_on=["subtotal", "discount"])
    def discount_amount(self) -> float:
        """Сумма скидки"""
        print(self.subtotal)
        return self.subtotal() * (self.discount / 100)
    
    @computed_property(depends_on=["subtotal", "discount_amount"])
    def total(self) -> float:
        """Итоговая сумма"""
        print(self.subtotal)
        return self.subtotal() - self.discount_amount()
    
    @computed_property(depends_on=["total"])
    def total_formatted(self) -> str:
        """Форматированная итоговая сумма"""
        return f"{self.total():.2f} ₽"


class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Пример 3: Вычисляемые свойства")
        
        self.vm = CalculatorViewModel()
        
        # Виджеты ввода
        self.price_edit = QDoubleSpinBox()
        self.price_edit.setRange(0, 1000000)
        self.price_edit.setSuffix(" ₽")
        
        self.quantity_spin = QDoubleSpinBox()
        self.quantity_spin.setRange(1, 1000)
        
        self.discount_spin = QDoubleSpinBox()
        self.discount_spin.setRange(0, 100)
        self.discount_spin.setSuffix(" %")
        
        # Виджеты для вычисляемых значений (только чтение)
        self.subtotal_label = QLabel()
        self.discount_label = QLabel()
        self.total_label = QLabel()
        self.total_label.setStyleSheet("font-size: 18px; font-weight: bold;")
        
        # Привязка входных данных (2-way)
        self.vm.price @ self.price_edit
        self.vm.quantity @ self.quantity_spin
        self.vm.discount @ self.discount_spin

        # Привязка вычисляемых значений (1-way, только чтение)
        self.vm.subtotal >> self.subtotal_label
        self.vm.discount_amount >> self.discount_label
        self.vm.total_formatted >> self.total_label
        
        # Компоновка
        layout = QVBoxLayout()
        layout.addWidget(QLabel("Цена:"))
        layout.addWidget(self.price_edit)
        layout.addWidget(QLabel("Количество:"))
        layout.addWidget(self.quantity_spin)
        layout.addWidget(QLabel("Скидка:"))
        layout.addWidget(self.discount_spin)
        
        layout.addWidget(QLabel("<hr>"))
        layout.addWidget(QLabel("Подытог:"))
        layout.addWidget(self.subtotal_label)
        layout.addWidget(QLabel("Скидка:"))
        layout.addWidget(self.discount_label)
        layout.addWidget(QLabel("<hr>"))
        layout.addWidget(QLabel("Итого:"))
        layout.addWidget(self.total_label)
        
        self.setLayout(layout)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec())
