import sys
import json
import socket
import subprocess
import threading
import time
from PyQt6.QtCore import Qt, pyqtSignal, QObject
from PyQt6.QtWidgets import QApplication, QVBoxLayout, QHBoxLayout, QWidget, QFrame
from qfluentwidgets import (PrimaryPushButton, PushButton, SubtitleLabel, 
                            MessageBox, InfoBar, InfoBarPosition, BodyLabel, CardWidget, setTheme, Theme)
import websocket

# --- НАСТРОЙКИ ---
SERVER_IP = "192.168.0.8"  # <--- ВПИШИ СЮДА IP ТВОЕГО КОНТЕЙНЕРА!
SERVER_PORT = "8000"
VH_PATH = "vhui64.exe"     # Программа должна лежать в той же папке
VH_DEVICE_ADDRESS = "Rutoken.31" # Аппаратный ID твоего Рутокена
CLIENT_NAME = socket.gethostname() # Имя текущего компьютера
# -----------------

class WorkerSignals(QObject):
    state_changed = pyqtSignal(dict)
    command_received = pyqtSignal(str)
    prompt_received = pyqtSignal(str)
    notify_received = pyqtSignal(str)

class WsClient(threading.Thread):
    def __init__(self, signals: WorkerSignals):
        super().__init__()
        self.signals = signals
        self.ws = None
        self.running = True

    def run(self):
        while self.running:
            try:
                self.ws = websocket.WebSocketApp(
                    f"ws://{SERVER_IP}:{SERVER_PORT}/ws/{CLIENT_NAME}",
                    on_message=self.on_message,
                    on_error=self.on_error,
                    on_close=self.on_close
                )
                self.ws.run_forever()
            except Exception as e:
                time.sleep(2) # Переподключение при сбое

    def on_message(self, ws, message):
        data = json.loads(message)
        msg_type = data.get("type")
        
        if msg_type == "state":
            self.signals.state_changed.emit(data)
        elif msg_type == "command":
            self.signals.command_received.emit(data.get("cmd"))
        elif msg_type == "prompt_request":
            self.signals.prompt_received.emit(data.get("from"))
        elif msg_type == "notify":
            self.signals.notify_received.emit(data.get("text"))

    def on_error(self, ws, error):
        pass

    def on_close(self, ws, close_status_code, close_msg):
        pass

    def send_action(self, action: str, extra: dict = None):
        if self.ws and self.ws.sock and self.ws.sock.connected:
            msg = {"action": action}
            if extra:
                msg.update(extra)
            self.ws.send(json.dumps(msg))

class EcpClientWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.current_owner = None
        self.signals = WorkerSignals()
        self.ws_thread = WsClient(self.signals)
        self.setup_ui()
        self.setup_signals()
        
        # Запускаем фоновый поток для связи с сервером
        self.ws_thread.start()

    def setup_ui(self):
        self.setWindowTitle("Менеджер ЭЦП Рутокен")
        self.resize(420, 220)
        self.setStyleSheet("background-color: #202020; color: white;")
        
        layout = QVBoxLayout(self)
        layout.setContentsMargins(20, 20, 20, 20)
        layout.setSpacing(15)
        
        # Используем обычный QFrame вместо CardWidget, чтобы рамка не выглядела как кнопка
        self.card = QFrame(self)
        self.card.setStyleSheet("""
            QFrame {
                background-color: #2b2b2b;
                border: 1px solid #3a3a3a;
                border-radius: 8px;
            }
        """)
        card_layout = QVBoxLayout(self.card)
        card_layout.setContentsMargins(15, 20, 15, 20)
        card_layout.setSpacing(10)
        
        # Метка статуса с запасом по высоте, чтобы текст и иконки не обрезались
        self.status_label = SubtitleLabel("Подключение к серверу...", self)
        self.status_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.status_label.setMinimumHeight(35)
        
        self.owner_label = BodyLabel("", self)
        self.owner_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        
        card_layout.addWidget(self.status_label)
        card_layout.addWidget(self.owner_label)
        layout.addWidget(self.card)
        
        # Кнопки управления
        btn_layout = QHBoxLayout()
        self.btn_connect = PrimaryPushButton("Подключить ЭЦП", self)
        self.btn_disconnect = PushButton("Отключить", self)
        
        self.btn_connect.clicked.connect(self.on_connect_clicked)
        self.btn_disconnect.clicked.connect(self.on_disconnect_clicked)
        
        self.btn_connect.setEnabled(False)
        self.btn_disconnect.setEnabled(False)
        
        btn_layout.addWidget(self.btn_connect)
        btn_layout.addWidget(self.btn_disconnect)
        layout.addLayout(btn_layout)

if __name__ == '__main__':
    setTheme(Theme.DARK)
    app = QApplication(sys.argv)
    window = EcpClientWindow()
    window.show()
    sys.exit(app.exec())