import { reactive, markRaw } from 'vue';
import { SignalingClient } from '../services/SignalingClient';
import { WebRtcController } from '../services/WebRtcController';
import { VideoRecorder } from '../services/VideoRecorder';
import { loadProto } from '../proto/controlMessage';

// 远程视频录制器（基于浏览器原生 MediaRecorder）。
const videoRecorder = new VideoRecorder();

// 与 Android/Flutter 端一致的 ICE 配置（请按需替换为自己的 TURN 凭据）。
export const DEFAULT_ICE_SERVERS = [
  // 公共 TURN（relay 兜底）：UDP + TCP 两种传输，TCP 用于 UDP 被防火墙拦截的网络。
  { urls: 'stun:175.178.213.60:3478' },
  { urls: 'turn:175.178.213.60:3478', username: 'fanhuitong', credential: 'Fan19961207..' },
  { urls: 'turn:175.178.213.60:3478?transport=tcp', username: 'fanhuitong', credential: 'Fan19961207..' },
  { urls: 'stun:47.242.112.133:3478' },
  { urls: 'turn:47.242.112.133:3478', username: 'ttstd', credential: 'fanhuitong' },
  // 内网 TURN（与被控端同局域网时可用）。
  // { urls: 'stun:192.168.5.224:3478' },
  // { urls: 'turn:192.168.100.224:3478', username: 'tt', credential: 'fht' },
  // { urls: 'turn:192.168.100.224:3478?transport=tcp', username: 'tt', credential: 'fht' },
  //   { urls: 'stun:stun.l.google.com:19302' },
  //   { urls: 'stun:stun1.l.google.com:19302' },
  //   { urls: 'stun:stun2.l.google.com:19302' },
];

export const store = reactive({
  serverUrl: 'wss://www.ttstd.com/signal',
  deviceId: '',
  targetDeviceId: '',
  iceServers: DEFAULT_ICE_SERVERS,

  protoReady: false,
  signalingConnected: false,
  signalingConnecting: false,
  registered: false,
  rtcConnected: false,
  dataChannelOpen: false,
  statusText: '未连接',
  error: '',

  controlledDevices: [],
  stats: null,
  remoteStream: null,
  // 被控端上报的当前实际采集分辨率（宽/高/帧率），用于与分辨率下拉框保持一致。
  currentResolution: null,

  // 远程视频录制状态
  recording: false,
  recordStatus: '',
});

let signaling = null;
let webrtc = null;

export async function initProto() {
  await loadProto();
  store.protoReady = true;
}

function parsePayload(payload) {
  if (!payload) return {};
  if (typeof payload === 'string') {
    try { return JSON.parse(payload); } catch { return {}; }
  }
  return payload;
}

export function connectSignaling() {
  store.error = '';
  const deviceId = store.deviceId.trim();
  if (!deviceId) { store.error = '请填写本机设备 ID'; return; }

  store.signalingConnecting = true;
  signaling = new SignalingClient({
    serverUrl: store.serverUrl.trim(),
    deviceId,
    onConnected: () => {
      store.signalingConnected = true;
      store.signalingConnecting = false;
      store.statusText = '已连接信令服务器';
      refreshDevices();
    },
    onDisconnected: () => {
      store.signalingConnected = false;
      store.signalingConnecting = false;
      store.registered = false;
      store.statusText = '已断开信令连接';
    },
    onError: (e) => {
      store.signalingConnecting = false;
      store.error = '信令错误: ' + e;
    },
    onMessage: handleSignalMessage,
  });
  signaling.connect();
}

function handleSignalMessage(msg) {
  switch ((msg.type || '').toUpperCase()) {
    case 'REGISTER_SUCCESS':
      store.registered = true;
      store.statusText = '注册成功 (CONTROLLER)';
      break;
    case 'DEVICE_LIST': {
      const list = msg.controlled || [];
      store.controlledDevices = Array.isArray(list) ? list : [];
      if (!store.controlledDevices.includes(store.targetDeviceId)) store.targetDeviceId = '';
      break;
    }
    case 'ANSWER': {
      store.statusText = '被控端已接受，正在建立连接...';
      if (webrtc) {
        webrtc.handleAnswer(parsePayload(msg.payload).sdp).catch((e) => {
          store.error = '设置远端描述失败: ' + (e?.message || e);
        });
      }
      break;
    }
    case 'ICE_CANDIDATE':
      webrtc && webrtc.handleIceCandidate(parsePayload(msg.payload));
      break;
    case 'TARGET_OFFLINE':
      store.error = msg.payload || '目标被控端不在线，请确认设备已开启并连接服务器';
      store.statusText = '连接失败';
      break;
    case 'CONNECTION_REJECTED':
    case 'REQUEST_ERROR':
    case 'REQUEST_TIMEOUT':
      store.error = msg.payload || '连接请求失败';
      store.statusText = '连接被拒绝';
      break;
  }
}

export function refreshDevices() {
  signaling && signaling.requestDeviceList();
}

export async function connectToDevice(targetId, authType = null, authValue = null) {
  if (!signaling || !store.signalingConnected) { store.error = '请先连接信令服务器'; return; }
  if (!targetId) { store.error = '请选择要控制的被控端设备'; return; }

  store.targetDeviceId = targetId;
  store.error = '';
  store.statusText = '正在发起连接...';
  // 清空上一次连接的录制提示。
  store.recording = false;
  store.recordStatus = '';

  if (webrtc) {
    // 切换目标设备会结束当前控制，若正在录制则先自动保存。
    if (videoRecorder.recording) await stopRecording();
    await webrtc.close();
    webrtc = null;
  }

  try {
    webrtc = new WebRtcController({
      iceServers: store.iceServers,
      deviceId: store.deviceId,
      targetDeviceId: targetId,
      signaling,
      onIceState: (s) => {
        if (s === 'connected') { store.rtcConnected = true; store.statusText = '已连接，可远程控制'; }
        else if (s === 'disconnected' || s === 'failed') { store.rtcConnected = false; store.statusText = '连接已断开'; }
      },
      onDataChannelState: (open) => { store.dataChannelOpen = open; },
      onStream: (stream) => { store.remoteStream = markRaw(stream); },
      onStats: (stats) => { store.stats = stats; },
      onError: (msg) => { if (msg) store.error = msg; },
      // 被控端上报当前实际采集分辨率，同步到 store 供 UI 展示/匹配预设。
      onResolutionReport: (res) => { store.currentResolution = res; },
    });
    await webrtc.createOffer(authType, authValue);
  } catch (e) {
    // 捕获 createOffer 阶段的所有异常，避免未处理的 Promise 拒绝导致浏览器中断脚本执行、
    // 间接影响 WebSocket 信令连接的存活。
    console.error('[connectToDevice] 创建 Offer 失败:', e);
    store.error = '创建连接失败: ' + (e?.message || e);
    store.statusText = '连接失败';
    if (webrtc) { await webrtc.close(); webrtc = null; }
  }
}

export async function disconnectDevice() {
  // 结束控制时若正在录制，先停止并自动保存（触发浏览器下载），再关闭连接。
  if (videoRecorder.recording) {
    await stopRecording();
  }
  if (webrtc) { await webrtc.close(); webrtc = null; }
  store.rtcConnected = false;
  store.dataChannelOpen = false;
  store.remoteStream = null;
  store.stats = null;
  store.currentResolution = null;
  // 注意：保留 recordStatus 的"已保存：文件名"提示，便于用户确认自动保存结果；
  // 仅复位 recording 标志，下次连接开始时再清空提示。
  store.recording = false;
  store.statusText = store.signalingConnected ? '已断开设备连接' : '未连接';
}

// 切换远程视频录制：开始 / 停止。
export function toggleRecording() {
  if (store.recording) return stopRecording();
  return startRecording();
}

// 开始录制当前远端视频流。
export function startRecording() {
  if (store.recording) return;
  if (!store.remoteStream) {
    store.error = '尚未接收到视频画面，无法录制';
    return;
  }
  if (!videoRecorder.isSupported) {
    store.error = '当前浏览器不支持 MediaRecorder 录制';
    return;
  }
  try {
    const ok = videoRecorder.start(store.remoteStream);
    if (ok) {
      store.recording = true;
      store.recordStatus = '录制中…';
    }
  } catch (e) {
    store.recordStatus = '';
    store.error = '开始录制失败: ' + (e?.message || e);
  }
}

// 停止录制并触发浏览器下载。
export async function stopRecording() {
  const result = await videoRecorder.stop();
  store.recording = false;
  if (result) {
    // 通过 Blob URL 触发浏览器下载（纯前端唯一"保存"途径）。
    const a = document.createElement('a');
    a.href = result.url;
    a.download = result.filename;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    store.recordStatus = '已保存：' + result.filename;
    // 下载完成后延迟释放 ObjectURL，避免下载被浏览器中断。
    setTimeout(() => URL.revokeObjectURL(result.url), 30000);
  } else {
    store.recordStatus = '录制已停止';
  }
  return result;
}

export function disconnectSignaling() {
  disconnectDevice();
  if (signaling) { signaling.disconnect(); signaling = null; }
  store.signalingConnected = false;
  store.signalingConnecting = false;
  store.registered = false;
  store.controlledDevices = [];
}

// 控制指令转发（供 UI 组件调用）
export function sendTouch(x, y) { return webrtc && webrtc.sendTouch(x, y); }
export function sendSwipe(x1, y1, x2, y2, duration) { return webrtc && webrtc.sendSwipe(x1, y1, x2, y2, duration); }
export function sendLongPress(x, y) { return webrtc && webrtc.sendLongPress(x, y); }
export function sendMotionEvent(action, x, y) { return webrtc && webrtc.sendMotionEvent(action, x, y); }
export function sendKey(keyCode) { return webrtc && webrtc.sendKey(keyCode); }
// 请求被控端切换屏幕采集分辨率（width<=0 表示原生分辨率；height<=0 时按 width 长边依宽高比缩放）
export function sendResolutionChange(width, height, fps) { return webrtc && webrtc.sendResolutionChange(width, height, fps); }
