<template>
  <div class="yh-printer-fab-root">
    <!-- 悬浮球（可拖动） -->
    <div
      ref="fabRef"
      class="printer-fab"
      :class="{dragging: isDragging}"
      :style="fabStyle"
      :title="statusTitle"
      @mousedown="onMouseDown">
      <svg class="printer-fab-icon" viewBox="0 0 1024 1024" width="22" height="22">
        <path
          d="M819.2 307.2h-51.2V153.6c0-28.16-23.04-51.2-51.2-51.2H307.2c-28.16 0-51.2 23.04-51.2 51.2v153.6H204.8c-84.992 0-153.6 68.608-153.6 153.6v256c0 28.16 23.04 51.2 51.2 51.2h102.4v102.4c0 28.16 23.04 51.2 51.2 51.2h512c28.16 0 51.2-23.04 51.2-51.2v-102.4h102.4c28.16 0 51.2-23.04 51.2-51.2v-256c0-84.992-68.608-153.6-153.6-153.6z m-460.8-102.4h307.2v102.4H358.4V204.8z m307.2 665.6H358.4v-204.8h307.2v204.8z m204.8-153.6h-51.2v-51.2c0-28.16-23.04-51.2-51.2-51.2H256c-28.16 0-51.2 23.04-51.2 51.2v51.2H153.6v-204.8c0-28.16 23.04-51.2 51.2-51.2h614.4c28.16 0 51.2 23.04 51.2 51.2v204.8z"
          fill="currentColor"/>
        <path
          d="M742.4 486.4m-38.4 0a38.4 38.4 0 1 0 76.8 0 38.4 38.4 0 1 0-76.8 0Z"
          fill="currentColor"/>
      </svg>
      <span class="printer-fab-dot" :class="statusClass"></span>
    </div>

    <!-- 配置弹框 -->
    <el-dialog v-model="visible" title="打印机设置" width="380px" :append-to-body="true">
      <div class="printer-config">
        <!-- 连接状态 -->
        <div class="printer-status-row">
          <span class="status-dot" :class="statusClass"></span>
          <span class="status-text">{{ statusText }}</span>
        </div>

        <el-divider content-position="left">打印机</el-divider>

        <!-- 使用默认打印机开关：开启时打印不弹出选择框，直接用下方选中的打印机 -->
        <div class="printer-default-switch">
          <span>使用默认打印机</span>
          <el-switch v-model="useDefault" @change="onUseDefaultChange" />
        </div>

        <template v-if="printers.length === 0">
          <div class="printer-empty">{{ status === 'connected' ? '未检测到打印机' : '连接后显示打印机列表' }}</div>
        </template>
        <template v-else>
          <div
            v-for="p in printers"
            :key="p.name"
            class="printer-item"
            @click="selectedPrinter = p.name">
            <span class="printer-radio" :class="{active: selectedPrinter === p.name}"></span>
            <span class="printer-name">{{ p.displayName }}</span>
            <span class="printer-state" :class="`state-${p.statusText}`">{{ p.statusText }}</span>
            <span v-if="p.isDefault" class="printer-default">默认</span>
          </div>
        </template>

        <el-divider content-position="left">操作</el-divider>

        <div
          v-if="status === 'retry_stopped'"
          class="printer-action"
          @click="manualReconnect">
          重新连接
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script setup>
  import {ref, computed, onMounted, onBeforeUnmount} from 'vue';
  import {ElDialog, ElDivider, ElSwitch, ElMessage} from 'element-plus';
  import {usePrinterClient} from '../libs/usePrinterClient';

  const {status, printers, selectedPrinter, client} = usePrinterClient();

  const visible = ref(false);

  /** localStorage key：是否使用默认打印机（关闭手动选择） */
  const USE_DEFAULT_KEY = 'hiprint-use-default-printer';
  /** localStorage key：悬浮球位置（"left,top"） */
  const FAB_POS_KEY = 'hiprint-printer-fab-pos';
  /** 拖动判定阈值（px）：移动小于此值视为点击 */
  const DRAG_THRESHOLD = 4;
  /** 悬浮球尺寸 + 距视口边缘留白 */
  const FAB_SIZE = 48;
  const FAB_MARGIN = 8;

  /** 是否使用默认打印机（开启时不手动选择，走服务端默认） */
  const useDefault = ref(localStorage.getItem(USE_DEFAULT_KEY) === '1');

  // ===== 悬浮球拖动 =====
  const fabRef = ref(null);
  const isDragging = ref(false);
  /** 悬浮球位置：默认右下角 */
  const fabPos = ref(loadFabPos());
  // 拖动过程临时状态
  let dragStart = null; // {mouseX, mouseY, origLeft, origTop, moved}

  function loadFabPos() {
    try {
      const saved = localStorage.getItem(FAB_POS_KEY);
      if (saved) {
        const [left, top] = saved.split(',').map(Number);
        if (Number.isFinite(left) && Number.isFinite(top)) return {left, top};
      }
    } catch {}
    return null; // null → 用 CSS 默认右下角
  }

  const fabStyle = computed(() => {
    if (fabPos.value == null) return {}; // 用 CSS 的 right/bottom 默认值
    return {left: fabPos.value.left + 'px', top: fabPos.value.top + 'px', right: 'auto', bottom: 'auto'};
  });

  function onMouseDown(e) {
    dragStart = {
      mouseX: e.clientX,
      mouseY: e.clientY,
      origLeft: fabPos.value ? fabPos.value.left : window.innerWidth - FAB_SIZE - 24,
      origTop: fabPos.value ? fabPos.value.top : window.innerHeight - FAB_SIZE - 24,
      moved: false,
    };
    document.addEventListener('mousemove', onMouseMove);
    document.addEventListener('mouseup', onMouseUp);
  }

  function onMouseMove(e) {
    if (!dragStart) return;
    const dx = e.clientX - dragStart.mouseX;
    const dy = e.clientY - dragStart.mouseY;
    if (!dragStart.moved && Math.hypot(dx, dy) < DRAG_THRESHOLD) return;
    dragStart.moved = true;
    isDragging.value = true;

    let left = dragStart.origLeft + dx;
    let top = dragStart.origTop + dy;
    // 限制在视口内
    left = Math.max(FAB_MARGIN, Math.min(left, window.innerWidth - FAB_SIZE - FAB_MARGIN));
    top = Math.max(FAB_MARGIN, Math.min(top, window.innerHeight - FAB_SIZE - FAB_MARGIN));
    fabPos.value = {left, top};
  }

  function onMouseUp() {
    document.removeEventListener('mousemove', onMouseMove);
    document.removeEventListener('mouseup', onMouseUp);
    const wasMoved = dragStart && dragStart.moved;
    isDragging.value = false;
    if (wasMoved && fabPos.value) {
      // 拖动结束：持久化位置
      try {
        localStorage.setItem(FAB_POS_KEY, `${fabPos.value.left},${fabPos.value.top}`);
      } catch {}
    }
    // 未移动 → 视为点击，打开弹框
    if (!wasMoved) {
      visible.value = true;
    }
    dragStart = null;
  }

  // ===== 开关：使用默认打印机 =====
  function onUseDefaultChange(val) {
    try {
      localStorage.setItem(USE_DEFAULT_KEY, val ? '1' : '0');
    } catch {}
  }

  // ===== 连接状态 =====
  const statusClass = computed(
    () =>
      ({
        connected: 'dot-success',
        connecting: 'dot-warning',
        disconnected: 'dot-danger',
        retry_stopped: 'dot-danger',
      })[status.value]
  );

  const statusText = computed(
    () =>
      ({
        connected: '已连接',
        connecting: '连接中',
        disconnected: '未连接',
        retry_stopped: '连接失败，请手动重连',
      })[status.value]
  );

  const statusTitle = computed(() => {
    const tip = statusText.value;
    const sel = useDefault.value ? ' · 默认' : selectedPrinter.value ? ` · ${selectedPrinter.value}` : '';
    return `${tip}${sel}`;
  });

  function manualReconnect() {
    client.manualReconnect();
    ElMessage.info('正在重新连接...');
  }

  // 组件卸载时清理可能残留的拖动监听
  onBeforeUnmount(() => {
    document.removeEventListener('mousemove', onMouseMove);
    document.removeEventListener('mouseup', onMouseUp);
  });
</script>

<style scoped>
  /* 悬浮球 */
  .printer-fab {
    position: fixed;
    right: 24px;
    bottom: 24px;
    width: 48px;
    height: 48px;
    border-radius: 50%;
    background: var(--el-color-primary, #409eff);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
    z-index: 9999;
    transition: transform 0.2s;
    user-select: none;
  }
  .printer-fab:hover {
    transform: scale(1.08);
  }
  .printer-fab.dragging {
    cursor: grabbing;
    transform: none;
    opacity: 0.85;
  }
  .printer-fab-icon {
    pointer-events: none;
  }
  .printer-fab-dot {
    position: absolute;
    top: 2px;
    right: 2px;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    border: 2px solid #fff;
  }

  /* 状态色 */
  .status-dot {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
  }
  .dot-success {
    background: #67c23a;
  }
  .dot-warning {
    background: #e6a23c;
  }
  .dot-danger {
    background: #f56c6c;
  }

  /* Dialog 内容 */
  .printer-status-row {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
  }
  .printer-status-row .status-text {
    font-weight: 600;
  }
  .printer-default-switch {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 6px 4px;
    font-size: 13px;
  }
  .printer-item {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 4px;
    cursor: pointer;
    border-radius: 4px;
  }
  .printer-item:hover {
    background: var(--el-fill-color-light, #f5f7fa);
  }
  .printer-radio {
    width: 12px;
    height: 12px;
    border: 2px solid #c0c4cc;
    border-radius: 50%;
    flex-shrink: 0;
  }
  .printer-radio.active {
    border-color: var(--el-color-primary);
    background: var(--el-color-primary);
    box-shadow: inset 0 0 0 2px #fff;
  }
  .printer-name {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .printer-state {
    font-size: 11px;
    padding: 1px 5px;
    border-radius: 3px;
    color: #909399;
    background: #f4f4f5;
  }
  .printer-state.state-空闲 {
    color: #67c23a;
    background: #f0f9eb;
  }
  .printer-state.state-打印中 {
    color: #e6a23c;
    background: #fdf6ec;
  }
  .printer-default {
    font-size: 11px;
    color: var(--el-color-primary);
  }
  .printer-empty {
    padding: 16px 4px;
    text-align: center;
    color: #909399;
    font-size: 13px;
  }
  .printer-action {
    padding: 8px 4px;
    color: var(--el-color-primary);
    cursor: pointer;
    border-radius: 4px;
  }
  .printer-action:hover {
    background: var(--el-fill-color-light, #f5f7fa);
  }
</style>
