<script setup>
import { ref, watch, onMounted, onUnmounted } from 'vue';
import { store, sendKeyDown, sendKeyUp, sendResolutionChange, toggleRecording } from '../store/controllerStore';

// Android KeyEvent 键值（与被控端 SystemInputUtils 注入一致）
const keys = [
  { label: '主页', code: 3 },     // KEYCODE_HOME
  { label: '返回', code: 4 },     // KEYCODE_BACK
  { label: '多任务', code: 187 }, // KEYCODE_APP_SWITCH
  { label: '菜单', code: 82 },    // KEYCODE_MENU
  { label: '音量 +', code: 24 },  // KEYCODE_VOLUME_UP
  { label: '音量 -', code: 25 },  // KEYCODE_VOLUME_DOWN
  { label: '电源', code: 26 },    // KEYCODE_POWER
];

// 分辨率预设：width 为长边像素；0 表示被控端原生分辨率；
// height 传 0（由被控端按屏幕宽高比自动计算），fps 传 0（沿用当前帧率）。
const resolutionPresets = [
  { label: '原始画质', width: 0, height: 0, fps: 0 },
  { label: '1080P', width: 1920, height: 0, fps: 0 },
  { label: '720P', width: 1280, height: 0, fps: 0 },
  { label: '480P', width: 854, height: 0, fps: 0 },
];
// 注意：<option :value="p.width"> 的 value 是数字，Vue 的 v-model 会按数字写入，
// 因此这里也必须用数字（不能用字符串 '0'），否则默认选中项与比较逻辑会类型不一致。
const selectedResolution = ref(0);

// 帧率档位：默认常用档位，收到被控端上报的 supported_fps 后以上报列表为准。
const fpsOptions = ref([15, 24, 30, 60]);
const selectedFps = ref(0); // 0 表示尚未同步到被控端当前帧率

function pressDown(code) {
  if (!store.dataChannelOpen) return;
  sendKeyDown(code);
}
function pressUp(code) {
  if (!store.dataChannelOpen) return;
  sendKeyUp(code);
}

// ----- 键盘捕获输入（真实键盘打字） -----
// 将浏览器 KeyboardEvent.key / .code 映射为 Android KeyEvent 键值。
// 覆盖字母、数字、空格、回车、退格、制表、方向键、修饰键与常用符号。
const KEY_MAP = {
  // 字母
  a: 29, b: 30, c: 31, d: 32, e: 33, f: 34, g: 35, h: 36, i: 37, j: 38, k: 39,
  l: 40, m: 41, n: 42, o: 43, p: 44, q: 45, r: 46, s: 47, t: 48, u: 49, v: 50,
  w: 51, x: 52, y: 53, z: 54,
  // 数字（主键盘）
  '0': 7, '1': 8, '2': 9, '3': 10, '4': 11, '5': 12, '6': 13, '7': 14, '8': 15, '9': 16,
  // 控制键
  Enter: 66, Backspace: 67, Tab: 61, Space: 62, Delete: 112, Escape: 111,
  ArrowLeft: 21, ArrowUp: 19, ArrowRight: 22, ArrowDown: 20,
  Home: 3, End: 123, PageUp: 92, PageDown: 93, Insert: 124,
  '`': 68, '-': 69, '=': 70, '[': 71, ']': 72, '\\': 73, ';': 74, '\'': 75, ',': 55, '.': 56, '/': 76,
};
// 修饰键（按下保持，直到抬起）
const MODIFIER_MAP = {
  Shift: 59, Control: 113, Alt: 57, Meta: 117,
};

const keyInputRef = ref(null);
const keyLog = ref('');

function lookupKeyCode(e) {
  // 优先使用 e.code（如物理键位置稳定），再回退到 e.key。
  if (MODIFIER_MAP[e.key]) return { code: MODIFIER_MAP[e.key], modifier: true };
  if (KEY_MAP[e.key] !== undefined) return { code: KEY_MAP[e.key], modifier: false };
  if (KEY_MAP[e.code]) return { code: KEY_MAP[e.code], modifier: false };
  return null;
}

// 固定按键：按下/抬起分离（如电源键需要真实按下-抬起配对）
function onKeyCaptureDown(e) {
  if (!store.dataChannelOpen) return;
  const m = lookupKeyCode(e);
  if (!m) return;
  e.preventDefault();
  sendKeyDown(m.code);
}
function onKeyCaptureUp(e) {
  if (!store.dataChannelOpen) return;
  const m = lookupKeyCode(e);
  if (!m) return;
  e.preventDefault();
  sendKeyUp(m.code);
}

function focusKeyInput() {
  keyInputRef.value && keyInputRef.value.focus();
}

// 监听整个 window 的键盘事件，保证页面任意位置（不依赖聚焦到某个输入框）
// 按下键盘即可向被控端发送按键指令。移动端软键盘不触发 keydown，故保留输入框聚焦。
onMounted(() => {
  window.addEventListener('keydown', onKeyCaptureDown);
  window.addEventListener('keyup', onKeyCaptureUp);
});
onUnmounted(() => {
  window.removeEventListener('keydown', onKeyCaptureDown);
  window.removeEventListener('keyup', onKeyCaptureUp);
});

function onResolutionChange() {
  if (!store.dataChannelOpen) return;
  // 统一按数值匹配：v-model 写入的是数字，不能用 String() 再与数字比较。
  const preset = resolutionPresets.find((p) => p.width === Number(selectedResolution.value));
  if (preset) {
    sendResolutionChange(preset.width, preset.height, preset.fps);
  }
}

function onFpsChange() {
  if (!store.dataChannelOpen) return;
  const fps = Number(selectedFps.value);
  if (fps <= 0) return;
  // 仅切换帧率：分辨率沿用被控端最近上报的实际采集尺寸（0 表示原生）。
  const res = store.currentResolution;
  sendResolutionChange(res ? res.width : 0, res ? res.height : 0, fps);
}

// 被控端上报当前实际采集分辨率/帧率时，同步下拉框（避免 UI 与实际不一致）。
watch(() => store.currentResolution, (res) => {
  if (!res) return;
  const longEdge = Math.max(res.width, res.height);
  const preset = resolutionPresets.find((p) => p.width === longEdge);
  if (preset) selectedResolution.value = preset.width;

  // 帧率档位以被控端上报为准（按屏幕刷新率筛选）
  if (Array.isArray(res.supportedFps) && res.supportedFps.length > 0) {
    fpsOptions.value = res.supportedFps;
  }
  if (res.fps > 0 && fpsOptions.value.includes(res.fps)) {
    selectedFps.value = res.fps;
  }
});
</script>

<template>
  <div class="control-bar">
    <div class="resolution-row">
      <label class="resolution-label">分辨率:</label>
      <select
        class="resolution-select"
        v-model="selectedResolution"
        :disabled="!store.dataChannelOpen"
        @change="onResolutionChange"
      >
        <option v-for="p in resolutionPresets" :key="p.label" :value="p.width">
          {{ p.label }}
        </option>
      </select>
      <label class="resolution-label">帧率:</label>
      <select
        class="resolution-select"
        v-model="selectedFps"
        :disabled="!store.dataChannelOpen"
        @change="onFpsChange"
      >
        <option v-if="selectedFps === 0" :value="0" disabled>--</option>
        <option v-for="f in fpsOptions" :key="f" :value="f">{{ f }}fps</option>
      </select>

      <span class="resolution-current" v-if="store.currentResolution">
        当前: {{ store.currentResolution.width }}×{{ store.currentResolution.height }}@{{ store.currentResolution.fps }}fps
      </span>

      <span class="record-sep"></span>

      <!-- 录制按钮与状态包成一组，保证换行时二者始终同进同退、不被拆散 -->
      <div class="record-group">
        <button
          class="record-btn"
          :class="{ recording: store.recording }"
          :disabled="!store.rtcConnected"
          @click="toggleRecording"
        >
          {{ store.recording ? '停止录制' : '录制' }}
        </button>
        <span
          class="record-status"
          v-if="store.recordStatus"
          :title="store.recordStatus"
        >{{ store.recordStatus }}</span>
      </div>
    </div>

    <button
      v-for="k in keys"
      :key="k.code"
      class="key-btn"
      :disabled="!store.dataChannelOpen"
      @pointerdown.prevent="pressDown(k.code)"
      @pointerup.prevent="pressUp(k.code)"
      @pointerleave.prevent="pressUp(k.code)"
      @pointercancel.prevent="pressUp(k.code)"
    >
      {{ k.label }}
    </button>

    <div class="keyboard-capture">
      <label class="kb-label">键盘输入:</label>
      <input
        ref="keyInputRef"
        class="kb-input"
        type="text"
        readonly
        placeholder="已全局监听，直接在页面上打字即可（手机请点此聚焦）"
        :disabled="!store.dataChannelOpen"
        @click="focusKeyInput"
        @blur="keyLog = ''"
      />
      <span class="kb-hint">支持字母/数字/符号/方向键/修饰键组合</span>
    </div>
  </div>
</template>

<style scoped>
.record-sep {
  width: 1px;
  height: 22px;
  margin: 0 4px;
  background: #3a3f4b;
  flex-shrink: 0;
}

/* 录制按钮 + 状态作为一个不可拆分的整体参与换行 */
.record-group {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: nowrap;
  min-width: 0;
  max-width: 100%;
}

.record-btn {
  /* flex-shrink:0 + nowrap 是"永不换行"的关键：
     作为 flex 子项默认可被压缩到小于文字宽度，从而把"停止录制"挤成两行。 */
  flex: 0 0 auto;
  flex-shrink: 0;
  white-space: nowrap;
  word-break: keep-all;
  min-width: fit-content;
  padding: 8px 16px;
  border: 1px solid #3a3f4b;
  border-radius: 6px;
  background: #2b6cff;
  color: #fff;
  font-size: 14px;
  line-height: 1.2;
  cursor: pointer;
  transition: background-color .15s ease, border-color .15s ease;
}

.record-btn:hover:not(:disabled) { background: #1f5ce0; }

.record-btn:disabled {
  background: #3a3f4b;
  color: #888;
  cursor: not-allowed;
}

.record-btn.recording {
  background: #e5484d;
  border-color: #e5484d;
}

.record-btn.recording:hover:not(:disabled) { background: #cf3b40; }

.record-status {
  /* 空间不足时由状态文字收缩并省略，保证按钮文字完整、二者同处一行 */
  flex: 0 1 auto;
  min-width: 0;
  max-width: 180px;
  font-size: 13px;
  color: #ffb020;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 换行后竖线分隔符失去意义，反而造成视觉噪点 */
@media (max-width: 640px) {
  .record-sep { display: none; }
}

/* ----- 键盘捕获输入 ----- */
.keyboard-capture {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 8px;
  flex-wrap: wrap;
}

.kb-label {
  font-size: 14px;
  color: #cfd3dc;
  white-space: nowrap;
}

.kb-input {
  flex: 1 1 240px;
  min-width: 200px;
  padding: 7px 10px;
  border: 1px solid #3a3f4b;
  border-radius: 6px;
  background: #1b1e24;
  color: #fff;
  font-size: 14px;
  outline: none;
}

.kb-input:focus {
  border-color: #2b6cff;
}

.kb-input:disabled {
  background: #23262d;
  color: #888;
  cursor: not-allowed;
}

.kb-hint {
  font-size: 12px;
  color: #888;
  white-space: nowrap;
}
</style>
