import 'package:fixnum/fixnum.dart';
import 'package:flutter/services.dart';

import 'package:webrtc_controller_flutter/core/proto/control_message.pb.dart';

/// 控制指令构造工具，对应 Android 端 RemoteTouchView 的指令格式。
///
/// 指令通过 DataChannel 以 protobuf 二进制（[ControlMessage]）发送，
/// 被控端（WebRTCControlled）的 InputCommandHandler 负责解析执行。
class ControlCommands {
  ControlCommands._();

  /// 将 Flutter 的 [LogicalKeyboardKey] 转换为 Android 标准 [KeyEvent.keyCode]。
  ///
  /// 说明：Flutter 的 [LogicalKeyboardKey.keyId] 是 Unicode 抽象值（如字母 'w'
  /// 的 keyId 为 0x77=119），而 Android 端注入按键时使用的是 [KeyEvent.keyCode]
  /// （如 KEYCODE_W=50）。两者语义不同，若直接把 Flutter 的 keyId 当作 Android
  /// keyCode 发给被控端，'w' 会被误识别为 KEYCODE_F8(119) 等，导致触发系统组合键
  /// /功能键（屏幕乱跳、输入框无字符输入）。因此这里统一转换成 Android keyCode。
  static int toAndroidKeyCode(LogicalKeyboardKey key) {
    // 字母 a-z / A-Z：Android KEYCODE_A=29 起
    const a = 0x61; // 'a'
    const z = 0x7a; // 'z'
    const au = 0x41; // 'A'
    const zu = 0x5a; // 'Z'
    final id = key.keyId;
    if (id >= a && id <= z) return id - a + 29;
    if (id >= au && id <= zu) return id - au + 29;
    // 数字 0-9：Android KEYCODE_0=7 起
    if (id >= 0x30 && id <= 0x39) return id - 0x30 + 7;

    // 其余按键用 LogicalKeyboardKey 常量精确匹配，避免魔法数字。
    // 注意：LogicalKeyboardKey 重写了 ==/hashCode，不能作为 const map 的 key，
    // 因此使用普通（非 const）Map 字面量。
    const home = LogicalKeyboardKey.home;
    const end = LogicalKeyboardKey.end;
    final map = <LogicalKeyboardKey, int>{
      LogicalKeyboardKey.space: 62,
      LogicalKeyboardKey.enter: 66,
      LogicalKeyboardKey.numpadEnter: 66,
      LogicalKeyboardKey.backspace: 67,
      LogicalKeyboardKey.tab: 61,
      LogicalKeyboardKey.escape: 111,
      LogicalKeyboardKey.delete: 112,
      home: 122,
      end: 123,
      LogicalKeyboardKey.pageUp: 92,
      LogicalKeyboardKey.pageDown: 93,
      LogicalKeyboardKey.arrowLeft: 21,
      LogicalKeyboardKey.arrowUp: 19,
      LogicalKeyboardKey.arrowRight: 22,
      LogicalKeyboardKey.arrowDown: 20,
      // 功能键 F1-F12：Android 131..142
      LogicalKeyboardKey.f1: 131,
      LogicalKeyboardKey.f2: 132,
      LogicalKeyboardKey.f3: 133,
      LogicalKeyboardKey.f4: 134,
      LogicalKeyboardKey.f5: 135,
      LogicalKeyboardKey.f6: 136,
      LogicalKeyboardKey.f7: 137,
      LogicalKeyboardKey.f8: 138,
      LogicalKeyboardKey.f9: 139,
      LogicalKeyboardKey.f10: 140,
      LogicalKeyboardKey.f11: 141,
      LogicalKeyboardKey.f12: 142,
    };
    return map[key] ?? 0;
  }

  /// 单击指令。坐标 x/y 为相对于屏幕的百分比（0.0 ~ 1.0）。
  static ControlMessage touch(double x, double y) => ControlMessage(
        action: Action.TOUCH,
        x: x,
        y: y,
      );

  /// 滑动指令。坐标为相对百分比，duration 为毫秒。
  static ControlMessage swipe(
    double x1,
    double y1,
    double x2,
    double y2,
    int durationMs,
  ) =>
      ControlMessage(
        action: Action.SWIPE,
        x1: x1,
        y1: y1,
        x2: x2,
        y2: y2,
        duration: Int64(durationMs),
      );

  /// 按键指令。action: 0=按下, 1=抬起（对应 Android KeyEvent.ACTION_DOWN/UP）。
  static ControlMessage key(int keyCode, int action) => ControlMessage(
        action: Action.KEY,
        keyCode: keyCode,
        keyAction: action,
      );

  /// 长按指令。坐标 x/y 为相对于屏幕的百分比（0.0 ~ 1.0）。
  /// 对应 Android 端 RemoteTouchView.createLongPressCommand。
  static ControlMessage longPress(double x, double y) => ControlMessage(
        action: Action.LONG_PRESS,
        x: x,
        y: y,
      );

  /// 原始 MotionEvent 指令，用于实现"实时跟手"。
  /// action: 0=DOWN, 1=UP, 2=MOVE（对应 Android MotionEvent.ACTION_XXX）。
  static ControlMessage motionEvent(int action, double x, double y) =>
      ControlMessage(
        action: Action.MOTION_EVENT,
        motionAction: action,
        x: x,
        y: y,
      );

  /// 分辨率切换指令。
  /// [width] 目标长边/宽度（<=0 表示被控端原生分辨率）；
  /// [height] 目标高度（<=0 时由被控端按屏幕宽高比计算）；
  /// [fps] 目标帧率（<=0 表示沿用当前帧率）。
  static ControlMessage setResolution(int width, int height, int fps) =>
      ControlMessage(
        action: Action.SET_RESOLUTION,
        width: width,
        height: height,
        fps: fps,
      );

  /// 串流模式切换指令。
  /// [mode] 为 0=WebRTC 全托管 / 1=自编码（自建 MediaCodec 编解码 + video DataChannel 裸流透传）。
  static ControlMessage streamMode(int mode) => ControlMessage(
        action: Action.SET_STREAM_MODE,
        streamMode: mode,
      );
}
