#!/usr/bin/env python3
"""
手机键盘控制电脑 - 服务端
使用 Flask + Socket.IO 实现 WebSocket 通信
使用 pynput 模拟键盘输入
"""

import os
import socket
from flask import Flask, send_from_directory, request
from flask_socketio import SocketIO
from pynput.keyboard import Controller, Key, KeyCode
from pynput.mouse import Controller as MouseController, Button

# 获取包所在目录
PACKAGE_DIR = os.path.dirname(os.path.abspath(__file__))

app = Flask(__name__, static_folder=PACKAGE_DIR)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app, cors_allowed_origins="*", async_mode='threading', transports=['polling', 'websocket'])

keyboard = Controller()
mouse = MouseController()


def get_local_ip():
    """获取本机局域网 IP 地址"""
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    try:
        s.connect(('10.255.255.255', 1))
        ip = s.getsockname()[0]
    except:
        ip = '127.0.0.1'
    finally:
        s.close()
    return ip


@app.route('/')
def index():
    return send_from_directory(PACKAGE_DIR, 'index.html')


@socketio.on('connect')
def handle_connect():
    print(f'客户端连接：{request.sid}')


@socketio.on('disconnect')
def handle_disconnect():
    print(f'客户端断开：{request.sid}')


@socketio.on('key')
def handle_key(data):
    """处理键盘按键事件"""
    key = data.get('key', '')
    key_type = data.get('type', 'char')

    if key_type == 'special':
        if not handle_special_key(key):
            print(f'Unknown special key: {key}')
    else:
        keyboard.type(key)


@socketio.on('key_combo')
def handle_key_combo(data):
    """处理组合键 (如 Ctrl+Tab、Ctrl+C、Win+Space、Ctrl+Shift+C)"""
    key = data.get('key', '')
    ctrl = data.get('ctrl', False)
    ctrl_right = data.get('ctrl_right', False)
    alt = data.get('alt', False)
    alt_right = data.get('alt_right', False)
    win = data.get('win', False)
    shift = data.get('shift', False)
    shift_right = data.get('shift_right', False)

    # 构建修饰键列表
    modifiers = []
    if ctrl:
        modifiers.append(Key.ctrl)
    if ctrl_right:
        modifiers.append(Key.ctrl_r)
    if alt:
        modifiers.append(Key.alt)
    if alt_right:
        modifiers.append(Key.alt_r)
    if win:
        modifiers.append(Key.cmd)
    if shift:
        modifiers.append(Key.shift)
    if shift_right:
        modifiers.append(Key.shift_r)

    # 按顺序按下修饰键
    for mod in modifiers:
        keyboard.press(mod)

    # 按下目标键
    if len(key) == 1:
        keyboard.press(key.lower())
        keyboard.release(key.lower())
    else:
        # 特殊键
        handle_special_key(key)

    # 释放修饰键
    for mod in reversed(modifiers):
        keyboard.release(mod)


# ===== 鼠标控制 =====
@socketio.on('mouse_move')
def handle_mouse_move(data):
    """处理鼠标移动"""
    x = data.get('x', 0)
    y = data.get('y', 0)
    mouse.move(x, y)


@socketio.on('mouse_click')
def handle_mouse_click(data):
    """处理鼠标点击"""
    button = data.get('button', 'left')
    if button == 'left':
        mouse.click(Button.left)
    elif button == 'right':
        mouse.click(Button.right)
    elif button == 'middle':
        mouse.click(Button.middle)


@socketio.on('mouse_press')
def handle_mouse_press(data):
    """处理鼠标按键按下/释放（用于拖动）"""
    button = data.get('button', 'left')
    pressed = data.get('pressed', True)
    if button == 'left':
        if pressed:
            mouse.press(Button.left)
        else:
            mouse.release(Button.left)
    elif button == 'right':
        if pressed:
            mouse.press(Button.right)
        else:
            mouse.release(Button.right)
    elif button == 'middle':
        if pressed:
            mouse.press(Button.middle)
        else:
            mouse.release(Button.middle)


@socketio.on('mouse_scroll')
def handle_mouse_scroll(data):
    """处理鼠标滚轮"""
    direction = data.get('direction', 'up')
    if direction == 'up':
        mouse.scroll(0, 3)
    else:
        mouse.scroll(0, -3)


def handle_special_key(key):
    """处理特殊按键"""
    key_map = {
        # 基础控制键
        'Enter': Key.enter,
        'Backspace': Key.backspace,
        'Space': Key.space,
        'Tab': Key.tab,
        'Escape': Key.esc,
        'CapsLock': Key.caps_lock,

        # 修饰键
        'Ctrl': Key.ctrl,
        'CtrlRight': Key.ctrl_r,
        'Alt': Key.alt,
        'AltRight': Key.alt_r,
        'Shift': Key.shift,
        'ShiftRight': Key.shift_r,
        'Super': Key.cmd,
        'SuperRight': Key.cmd_r,
        'Menu': Key.menu,

        # 方向键
        'ArrowUp': Key.up,
        'ArrowDown': Key.down,
        'ArrowLeft': Key.left,
        'ArrowRight': Key.right,

        # 导航键
        'Insert': Key.insert,
        'Delete': Key.delete,
        'Home': Key.home,
        'End': Key.end,
        'PageUp': Key.page_up,
        'PageDown': Key.page_down,

        # 功能键
        'F1': Key.f1,
        'F2': Key.f2,
        'F3': Key.f3,
        'F4': Key.f4,
        'F5': Key.f5,
        'F6': Key.f6,
        'F7': Key.f7,
        'F8': Key.f8,
        'F9': Key.f9,
        'F10': Key.f10,
        'F11': Key.f11,
        'F12': Key.f12,

        # 其他
        'PrintScreen': Key.print_screen,
        'ScrollLock': Key.scroll_lock,
        'Pause': Key.pause,
    }

    if key in key_map:
        keyboard.press(key_map[key])
        keyboard.release(key_map[key])
        return True
    return False


def main():
    """命令行入口 - 直接启动"""
    # 从 cli 模块导入并运行
    from screen_keyboard.cli import cli
    cli()


if __name__ == '__main__':
    main()
