import sys
from PyQt6.QtWidgets import *
from PyQt6.QtCore import QThread, pyqtSignal, Qt
from PyQt6.QtGui import QIcon
import win32gui, win32api, win32con
import time, random, json, os


class KeyConfigWidget(QWidget):
    """单个按键配置组件"""

    def __init__(self, key_name, default_config):
        super().__init__()
        self.key_name = key_name
        self.config = default_config or {'enabled': False, 'interval': 10, 'jitter': 2}
        self.init_ui()

    def init_ui(self):
        layout = QHBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)

        # 启用复选框
        self.checkbox = QCheckBox(f"按键 [{self.key_name}]")
        self.checkbox.setChecked(self.config['enabled'])
        layout.addWidget(self.checkbox)

        # 间隔
        layout.addWidget(QLabel("间隔:"))
        self.interval_spin = QSpinBox()
        self.interval_spin.setRange(1, 60)
        self.interval_spin.setValue(self.config['interval'])
        layout.addWidget(self.interval_spin)
        layout.addWidget(QLabel("秒"))

        # 随机延迟
        layout.addWidget(QLabel("随机:"))
        self.jitter_spin = QSpinBox()
        self.jitter_spin.setRange(0, 10)
        self.jitter_spin.setValue(self.config['jitter'])
        layout.addWidget(self.jitter_spin)
        layout.addWidget(QLabel("秒"))

        layout.addStretch()

        # 连接信号
        self.checkbox.toggled.connect(self.on_toggle)
        self.on_toggle()

    def on_toggle(self):
        enabled = self.checkbox.isChecked()
        self.interval_spin.setEnabled(enabled)
        self.jitter_spin.setEnabled(enabled)

    def get_config(self):
        return {
            'enabled': self.checkbox.isChecked(),
            'interval': self.interval_spin.value(),
            'jitter': self.jitter_spin.value()
        }


class KeyWorker(QThread):
    """按键工作线程"""
    log_signal = pyqtSignal(str)

    def __init__(self, hwnd, key_name, config):
        super().__init__()
        self.hwnd = hwnd
        self.key_name = key_name
        self.config = config
        self.running = True

    def run(self):
        while self.running:
            if self.config['enabled']:
                self.press_key()

            # 随机间隔
            sleep_time = self.config['interval'] + random.uniform(-self.config['jitter'], self.config['jitter'])
            sleep_time = max(1, sleep_time)

            for _ in range(int(sleep_time * 2)):
                if not self.running:
                    break
                time.sleep(0.5)

    def press_key(self):
        """发送按键"""
        if not self.hwnd:
            return

        key_map = {
            '空格(跳跃)': win32con.VK_SPACE,
            '1': 0x31, '2': 0x32, '3': 0x33, '4': 0x34, '5': 0x35
        }

        vk = key_map.get(self.key_name)
        if vk:
            try:
                win32api.PostMessage(self.hwnd, win32con.WM_KEYDOWN, vk, 0)
                time.sleep(random.uniform(0.05, 0.15))
                win32api.PostMessage(self.hwnd, win32con.WM_KEYUP, vk, 0)
                key_type = "跳跃" if self.key_name == '空格(跳跃)' else f"技能 {self.key_name}"
                self.log_signal.emit(f"➡️ 执行 {key_type}")
            except Exception as e:
                self.log_signal.emit(f"❌ 按键 {self.key_name} 失败: {e}")


class WoWMultiKeyGUI(QMainWindow):
    def __init__(self):
        super().__init__()
        self.config_file = "wow_multikey_qt.json"
        self.config = self.load_config()
        self.workers = {}
        self.hwnd = None

        self.init_ui()
        self.find_wow_window()

    def init_ui(self):
        self.setWindowTitle("WoW多键控制器")
        self.setGeometry(100, 100, 700, 550)

        central = QWidget()
        self.setCentralWidget(central)
        layout = QVBoxLayout(central)

        # 窗口状态
        self.window_label = QLabel("正在查找窗口...")
        layout.addWidget(self.window_label)

        self.refresh_btn = QPushButton("刷新窗口")
        self.refresh_btn.clicked.connect(self.find_wow_window)
        layout.addWidget(self.refresh_btn)

        # 按键配置
        self.key_widgets = {}
        keys = ['空格(跳跃)', '1', '2', '3', '4', '5']

        scroll = QScrollArea()
        scroll.setWidgetResizable(True)
        scroll_widget = QWidget()
        scroll_layout = QVBoxLayout(scroll_widget)

        for key in keys:
            widget = KeyConfigWidget(key, self.config.get(key))
            scroll_layout.addWidget(widget)
            self.key_widgets[key] = widget

        scroll_layout.addStretch()
        scroll.setWidget(scroll_widget)
        layout.addWidget(scroll)

        # 按钮
        btn_layout = QHBoxLayout()
        self.start_btn = QPushButton("🚀 启动")
        self.start_btn.clicked.connect(self.start_all)
        self.stop_btn = QPushButton("⏹ 停止")
        self.stop_btn.clicked.connect(self.stop_all)
        self.stop_btn.setEnabled(False)

        btn_layout.addWidget(self.start_btn)
        btn_layout.addWidget(self.stop_btn)
        btn_layout.addStretch()
        layout.addLayout(btn_layout)

        # 日志
        self.log_text = QTextEdit()
        self.log_text.setReadOnly(True)
        self.log_text.setMaximumHeight(150)
        layout.addWidget(self.log_text)

        # 状态栏
        self.status_bar = self.statusBar()
        self.status_bar.showMessage("就绪")

    def load_config(self):
        if os.path.exists(self.config_file):
            try:
                with open(self.config_file, "r") as f:
                    return json.load(f)
            except:
                pass
        return {}

    def save_config(self):
        config = {key: widget.get_config() for key, widget in self.key_widgets.items()}
        with open(self.config_file, "w") as f:
            json.dump(config, f, indent=2)

    def find_wow_window(self):
        titles = ["魔兽世界", "World of Warcraft"]
        for title in titles:
            self.hwnd = win32gui.FindWindow(None, title)
            if self.hwnd:
                self.window_label.setText(f"✅ 已找到: {title}")
                self.log(f"成功绑定窗口: {title}")
                return
        self.window_label.setText("❌ 未找到游戏窗口")
        self.hwnd = None

    def log(self, message):
        self.log_text.append(f"[{time.strftime('%H:%M:%S')}] {message}")

    def start_all(self):
        if not self.hwnd:
            QMessageBox.warning(self, "警告", "未找到游戏窗口！")
            return

        any_enabled = any(w.get_config()['enabled'] for w in self.key_widgets.values())
        if not any_enabled:
            QMessageBox.warning(self, "警告", "请至少启用一个按键！")
            return

        self.save_config()

        # 启动工作线程
        for key_name, widget in self.key_widgets.items():
            config = widget.get_config()
            if config['enabled']:
                worker = KeyWorker(self.hwnd, key_name, config)
                worker.log_signal.connect(self.log)
                worker.start()
                self.workers[key_name] = worker

        self.start_btn.setEnabled(False)
        self.stop_btn.setEnabled(True)
        self.status_bar.showMessage("🟢 运行中")
        self.log("🎮 自动按键已启动")

    def stop_all(self):
        for worker in self.workers.values():
            worker.running = False
            worker.wait()

        self.workers.clear()
        self.start_btn.setEnabled(True)
        self.stop_btn.setEnabled(False)
        self.status_bar.showMessage("⏹️ 已停止")
        self.log("🛑 所有按键已停止")

    def closeEvent(self, event):
        if self.workers:
            reply = QMessageBox.question(self, "退出", "确认退出？")
            if reply == QMessageBox.StandardButton.Yes:
                self.stop_all()
                event.accept()
            else:
                event.ignore()
        else:
            event.accept()


def main():
    app = QApplication(sys.argv)
    window = WoWMultiKeyGUI()
    window.show()
    sys.exit(app.exec())


if __name__ == "__main__":
    main()