<style scoped lang="scss">
.remote-panel {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.device-status-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
  background: #1a1a2e;
  border-radius: 8px;
  color: #00ff88;
  font-family: 'Courier New', monospace;
  font-size: 14px;

  .status-left {
    display: flex;
    align-items: center;
    gap: 16px;
  }

  .status-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    display: inline-block;
    margin-right: 6px;

    &.busy { background: #ff4444; animation: blink 1s infinite; }
    &.idle { background: #00ff88; }
    &.init { background: #ffaa00; }
    &.fault { background: #ff0000; }
    &.maintenance { background: #ff8800; }
    &.sleep { background: #888888; }
  }

  @keyframes blink {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.3; }
  }

  .status-label {
    color: #aaa;
    font-size: 12px;
  }

  .status-value {
    color: #fff;
    font-weight: bold;
  }
}

.func-button-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 10px;

  .func-btn {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 16px 8px;
    border: 1px solid #ddd;
    border-radius: 10px;
    cursor: pointer;
    transition: all 0.2s;
    background: #f8f9fa;
    user-select: none;

    &:hover {
      background: #e8f4fd;
      border-color: #409eff;
      transform: translateY(-2px);
      box-shadow: 0 4px 12px rgba(64, 158, 255, 0.2);
    }

    &:active {
      transform: translateY(0);
      background: #d9ecff;
    }

    .func-icon {
      font-size: 24px;
      margin-bottom: 6px;
    }

    .func-name {
      font-size: 13px;
      font-weight: 600;
      color: #333;
      margin-bottom: 4px;
    }

    .func-price {
      font-size: 12px;
      color: #f56c6c;
      font-weight: 500;
    }
  }
}

.system-actions {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  padding: 12px 0;
  border-top: 1px solid #ebeef5;
  border-bottom: 1px solid #ebeef5;

  .action-btn {
    flex: 1;
    min-width: 100px;
  }
}

.order-info-card {
  background: #fffbf0;
  border: 1px solid #f0d78c;
  border-radius: 8px;
  padding: 12px 16px;
  margin-top: 8px;

  .order-title {
    font-weight: 600;
    color: #e6a23c;
    margin-bottom: 8px;
  }

  .order-row {
    display: flex;
    justify-content: space-between;
    font-size: 13px;
    color: #666;
    margin-bottom: 4px;

    span:last-child {
      color: #333;
      font-weight: 500;
    }
  }
}

.config-editor {
  margin-top: 8px;
  padding: 12px;
  background: #f5f7fa;
  border-radius: 8px;

  .config-title {
    font-weight: 600;
    margin-bottom: 10px;
    color: #333;
  }

  :deep(.el-form-item) {
    margin-bottom: 12px;
  }
}

.price-tag {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 4px;
  font-size: 12px;
  cursor: pointer;
  margin-left: 6px;

  &:hover {
    opacity: 0.8;
  }
}
</style>

<template>
  <div class="system-dialog-container">
    <el-dialog
        :title="'远程控制 — ' + deviceName"
        v-model="state.dialog.isShowDialog"
        width="800px"
        draggable
        destroy-on-close
        :close-on-click-modal="false"
        align-center
        @close="onClose">

      <div v-if="!state.ready" style="text-align:center;padding:60px 0;">
        <el-icon class="is-loading" style="font-size:32px;color:#409eff;"><Loading /></el-icon>
        <p style="color:#999;margin-top:12px;">正在连接设备...</p>
      </div>
      <div class="remote-panel" v-else>
        <!-- 设备状态栏 -->
        <div class="device-status-bar">
          <div class="status-left">
            <span>
              <span class="status-dot" :class="statusClass"></span>
              {{ statusLabel }}
            </span>
            <span><span class="status-label">运行时长</span> <span class="status-value">{{ uptimeDisplay }}</span></span>
            <span><span class="status-label">温度</span> <span class="status-value">{{ temperatureDisplay }}</span></span>
            <span><span class="status-label">PA壶</span> <span class="status-value" :style="{color: state.hasPa ? '#00ff88' : '#888'}">{{ u.fmt.fmtDict(state.hasPa ? '1' : '0', 'yes_no') }}</span></span>
          </div>
          <div>
            <el-button size="small" text type="primary" @click="refreshState" :loading="state.loading">
              <el-icon><Refresh /></el-icon> 刷新
            </el-button>
          </div>
        </div>

        <!-- 功能按钮面板 -->
        <div class="func-button-grid">
          <div class="func-btn" v-for="fn in functionButtons" :key="fn.key" @click="editPrice(fn)">
            <span class="func-icon">{{ fn.icon }}</span>
            <span class="func-name">{{ fn.name }}</span>
            <span class="func-price">{{ fn.price != null ? (fn.price / 100).toFixed(2) + '元/分钟' : '--' }}</span>
          </div>
        </div>

        <!-- 系统操作按钮 -->
        <div class="system-actions">
          <el-button class="action-btn" type="primary" plain @click="handleReadConfig" :loading="state.loading">
            <el-icon><Reading /></el-icon> 读取配置
          </el-button>
          <el-button class="action-btn" type="warning" plain @click="handleShowMsgbox" :loading="state.loading">
            <el-icon><ChatDotSquare /></el-icon> 屏幕消息
          </el-button>
          <el-button class="action-btn" type="success" plain @click="handleHideMsgbox" :loading="state.loading">
            <el-icon><CloseBold /></el-icon> 清除消息
          </el-button>
          <el-button class="action-btn" type="danger" plain @click="handleReboot" :loading="state.loading">
            <el-icon><SwitchButton /></el-icon> 重启设备
          </el-button>
        </div>

        <!-- 订单信息（仅忙碌时显示） -->
        <div class="order-info-card" v-if="state.deviceState === 'busy' && state.orderInfo">
          <div class="order-title">当前订单</div>
          <div class="order-row"><span>订单号</span><span>{{ state.orderInfo.order_id || '--' }}</span></div>
          <div class="order-row"><span>消费金额</span><span>{{ state.orderInfo.amount ? (state.orderInfo.amount / 100).toFixed(2) + '元' : '--' }}</span></div>
          <div class="order-row"><span>操作剩余</span><span>{{ state.orderInfo.operation_remain_time }}秒</span></div>
          <div class="order-row"><span>空闲剩余</span><span>{{ state.orderInfo.idle_remain_time }}秒</span></div>
          <div style="margin-top: 10px;">
            <el-button size="small" type="danger" @click="handleForceCloseOrder">
              强制结算
            </el-button>
          </div>
        </div>

        <!-- 配置编辑区 -->
        <div class="config-editor" v-if="state.showConfigEditor">
          <div class="config-title">设备配置编辑</div>
          <el-form :model="state.configForm" label-width="140px" size="small" inline>
            <el-form-item label="清水单价(元/分钟)">
              <el-input-number v-model="state.configForm.priceWater" :min="0" :precision="2" :step="0.1" size="small" controls-position="right"/>
            </el-form-item>
            <el-form-item label="泡沫单价(元/分钟)">
              <el-input-number v-model="state.configForm.priceFoam" :min="0" :precision="2" :step="0.1" size="small" controls-position="right"/>
            </el-form-item>
            <el-form-item label="吸尘单价(元/分钟)">
              <el-input-number v-model="state.configForm.priceCleaner" :min="0" :precision="2" :step="0.1" size="small" controls-position="right"/>
            </el-form-item>
            <el-form-item label="洗手单价(元/分钟)">
              <el-input-number v-model="state.configForm.priceTap" :min="0" :precision="2" :step="0.1" size="small" controls-position="right"/>
            </el-form-item>
            <el-form-item label="扩展单价(元/分钟)">
              <el-input-number v-model="state.configForm.priceUserExt" :min="0" :precision="2" :step="0.1" size="small" controls-position="right"/>
            </el-form-item>
            <el-form-item label="镀膜单价(元/分钟)">
              <el-input-number v-model="state.configForm.priceCoat" :min="0" :precision="2" :step="0.1" size="small" controls-position="right"/>
            </el-form-item>
            <el-form-item label="吹气单价(元/分钟)">
              <el-input-number v-model="state.configForm.priceBlow" :min="0" :precision="2" :step="0.1" size="small" controls-position="right"/>
            </el-form-item>
            <el-form-item label="场地费(元/分钟)">
              <el-input-number v-model="state.configForm.priceSpace" :min="0" :precision="2" :step="0.1" size="small" controls-position="right"/>
            </el-form-item>
            <el-form-item label="空闲超时(秒)">
              <el-input-number v-model="state.configForm.idleTimeout" :min="0" size="small" controls-position="right"/>
            </el-form-item>
            <el-form-item label="操作超时(秒)">
              <el-input-number v-model="state.configForm.operationTimeout" :min="0" size="small" controls-position="right"/>
            </el-form-item>
            <el-form-item label="提示音音量">
              <el-input-number v-model="state.configForm.soundVolume" :min="0" :max="100" size="small" controls-position="right"/>
            </el-form-item>
            <el-form-item label="屏幕左下文本">
              <el-input v-model="state.configForm.userMessage1" size="small" style="width:180px"/>
            </el-form-item>
            <el-form-item label="屏幕右下文本">
              <el-input v-model="state.configForm.userMessage2" size="small" style="width:180px"/>
            </el-form-item>
            <el-form-item label="时区(分钟)">
              <el-input-number v-model="state.configForm.timezone" :min="-720" :max="720" size="small" controls-position="right"/>
            </el-form-item>
            <el-form-item label="空闲超时策略">
              <el-input v-model="state.configForm.idleTimeoutStrategy" size="small" style="width:180px" placeholder="0=关机, 1=扣费"/>
            </el-form-item>
            <el-form-item label="清水泡沫联动">
              <el-input v-model="state.configForm.foamLinkMode" size="small" style="width:180px" placeholder="0=关, 1=开"/>
            </el-form-item>
            <el-form-item label="流量收费">
              <el-input v-model="state.configForm.motorFeeFlow" size="small" style="width:180px" placeholder="0=关, 1=开"/>
            </el-form-item>
          </el-form>
          <div style="margin-top: 10px;">
            <el-button type="primary" size="small" @click="handleWriteConfig" :loading="state.loading">应用配置</el-button>
            <el-button size="small" @click="state.showConfigEditor = false">收起</el-button>
          </div>
        </div>

        <!-- 价格快捷编辑弹窗 -->
        <el-dialog v-model="state.priceDialog.visible" :title="'修改单价 — ' + state.priceDialog.name" width="350px"
                   :close-on-click-modal="false" append-to-body>
          <div style="text-align:center; padding: 20px 0;">
            <div style="font-size: 14px; color: #666; margin-bottom: 12px;">当前单价：{{ (state.priceDialog.currentPrice / 100).toFixed(2) }} 元/分钟</div>
            <div style="display: flex; align-items: center; justify-content: center; gap: 8px;">
              <span>新单价：</span>
              <el-input-number v-model="state.priceDialog.newPriceYuan" :min="0" :precision="2" :step="0.1" size="default"/>
              <span>元/分钟</span>
            </div>
            <div style="font-size: 12px; color: #999; margin-top: 6px;">（{{ Math.round(state.priceDialog.newPriceYuan * 100) }} 分）</div>
          </div>
          <template #footer>
            <el-button @click="state.priceDialog.visible = false">取消</el-button>
            <el-button type="primary" @click="confirmPriceEdit" :loading="state.loading">确认修改</el-button>
          </template>
        </el-dialog>

        <!-- 屏幕消息弹窗 -->
        <el-dialog v-model="state.msgDialog.visible" title="发送屏幕消息" width="450px"
                   :close-on-click-modal="false" append-to-body>
          <el-form label-width="70px" size="default">
            <el-form-item label="标题">
              <el-input v-model="state.msgDialog.title" placeholder="消息标题"/>
            </el-form-item>
            <el-form-item label="内容">
              <el-input v-model="state.msgDialog.content" type="textarea" :rows="3" placeholder="消息内容"/>
            </el-form-item>
            <el-form-item label="显示时长">
              <el-input-number v-model="state.msgDialog.seconds" :min="1" :max="300"/> 秒
            </el-form-item>
          </el-form>
          <template #footer>
            <el-button @click="state.msgDialog.visible = false">取消</el-button>
            <el-button type="primary" @click="confirmShowMsgbox" :loading="state.loading">发送</el-button>
          </template>
        </el-dialog>
      </div>
    </el-dialog>
  </div>
</template>

<script setup lang="ts" name="WashDeviceRemoteDialog">
import {reactive, computed, watch} from 'vue';
import {Msg} from "/@/utils/message";
import {$body} from "/@/utils/request";
import u from '/@/utils/u';
import {ElMessage} from 'element-plus';
import {Refresh, Reading, ChatDotSquare, CloseBold, SwitchButton, Loading} from '@element-plus/icons-vue';

const emit = defineEmits(['refresh']);

const initState = () => ({
  ready: false,
  loading: false,
  deviceState: '',
  temperatureChip: null as number | null,
  uptimeMs: '',
  hasPa: false,
  orderInfo: null as any,
  showConfigEditor: false,
  configForm: {} as any,
  priceDialog: {
    visible: false,
    key: '',
    name: '',
    currentPrice: 0,
    newPriceYuan: 0,
  },
  msgDialog: {
    visible: false,
    title: '',
    content: '',
    seconds: 10,
  },
  dialog: {
    isShowDialog: false,
  },
});

const state = reactive(initState());

let productKey = '';
let deviceName = '';

const functionButtons = [
  {key: 'priceWater',     name: '清水',  icon: '🚿', price: null as number | null},
  {key: 'priceFoam',      name: '泡沫',  icon: '🫧', price: null as number | null},
  {key: 'priceCleaner',   name: '吸尘',  icon: '🌀', price: null as number | null},
  {key: 'priceTap',       name: '洗手',  icon: '🖐️', price: null as number | null},
  {key: 'priceUserExt',   name: '扩展',  icon: '🔧', price: null as number | null},
  {key: 'priceCoat',      name: '镀膜',  icon: '✨', price: null as number | null},
  {key: 'priceBlow',      name: '吹气',  icon: '💨', price: null as number | null},
  {key: 'priceSpace',     name: '场地费', icon: '🅿️', price: null as number | null},
];

const priceKeys = functionButtons.map(f => f.key);

const statusClass = computed(() => {
  const map: Record<string, string> = {busy: 'busy', idle: 'idle', init: 'init', fault: 'fault', maintenance: 'maintenance', sleep: 'sleep'};
  return map[state.deviceState] || '';
});

const statusLabel = computed(() => {
  return u.fmt.fmtDict(state.deviceState, 'WashDevice.status') || state.deviceState || '未知';
});

const uptimeDisplay = computed(() => {
  if (!state.uptimeMs) return '--';
  const ms = parseInt(state.uptimeMs);
  const h = Math.floor(ms / 3600000);
  const m = Math.floor((ms % 3600000) / 60000);
  return h > 0 ? `${h}时${m}分` : `${m}分`;
});

const temperatureDisplay = computed(() => {
  return state.temperatureChip != null ? `${state.temperatureChip}°C` : '--';
});

const open = (row: any) => {
  productKey = row.productKey;
  deviceName = row.deviceName;
  state.dialog.isShowDialog = true;
  loadDeviceState();
};

const onClose = () => {
  state.dialog.isShowDialog = false;
  Object.assign(state, initState());
};

const api = (url: string, data: any = {}) => {
  return $body(`/washDevice/remote/${url}`, {productKey, deviceName, ...data});
};

const loadDeviceState = async () => {
  state.loading = true;
  try {
    const res: any = await api('queryState');
    state.deviceState = res?.device_state?.state || '';
    state.uptimeMs = res?.device_state?.uptime_ms || '';
    state.temperatureChip = res?.device_state?.temperature_chip ?? null;
    state.hasPa = res?.device_state?.has_pa === '1' || res?.device_state?.has_pa === 1 || res?.device_state?.has_pa === true;
    state.orderInfo = res?.order_info || null;
  } catch (e) {
    Msg.message('查询设备状态失败', 'error');
  }

  // 自动加载设备配置，填充功能按钮价格
  try {
    const config: any = await api('readConfig');
    for (const fn of functionButtons) {
      fn.price = config?.[fn.key] ?? null;
    }
    state.configForm = fenToYuanConfig(config);
  } catch (e) {
    // 配置加载失败不影响面板使用，功能按钮显示 "--"
    for (const fn of functionButtons) {
      fn.price = null;
    }
  }

  state.ready = true;
  state.loading = false;
};

const refreshState = () => loadDeviceState();

const handleReadConfig = async () => {
  state.loading = true;
  try {
    const res: any = await api('readConfig');
    // 同步价格到功能按钮（保持fen）
    for (const fn of functionButtons) {
      fn.price = res?.[fn.key] ?? null;
    }
    state.configForm = fenToYuanConfig(res);
    state.showConfigEditor = true;
    Msg.message('配置读取成功', 'success');
  } catch (e) {
    Msg.message('读取配置失败', 'error');
  } finally {
    state.loading = false;
  }
};

const handleWriteConfig = async () => {
  state.loading = true;
  try {
    await api('writeConfig', {config: yuanToFenConfig(state.configForm)});
    // 同步更新按钮显示的价格
    for (const fn of functionButtons) {
      fn.price = Math.round(state.configForm[fn.key] * 100);
    }
    Msg.message('配置写入成功', 'success');
  } catch (e) {
    Msg.message('写入配置失败', 'error');
  } finally {
    state.loading = false;
  }
};

const editPrice = (fn: any) => {
  if (fn.price == null) {
    Msg.message('配置加载失败，无法修改价格，请点击「读取配置」重试', 'warning');
    return;
  }
  state.priceDialog.key = fn.key;
  state.priceDialog.name = fn.name;
  state.priceDialog.currentPrice = fn.price;
  state.priceDialog.newPriceYuan = parseFloat((fn.price / 100).toFixed(2));
  state.priceDialog.visible = true;
};

const confirmPriceEdit = async () => {
  const newPriceFen = Math.round(state.priceDialog.newPriceYuan * 100);
  state.loading = true;
  try {
    // 先读当前完整配置，修改单个价格后写回
    const fullConfig: any = await api('readConfig');
    fullConfig[state.priceDialog.key] = newPriceFen;
    await api('writeConfig', {config: fullConfig});
    // 更新显示
    const fn = functionButtons.find(f => f.key === state.priceDialog.key);
    if (fn) fn.price = newPriceFen;
    state.configForm[state.priceDialog.key] = newPriceFen;
    state.priceDialog.visible = false;
    Msg.message(`${state.priceDialog.name}价格已更新`, 'success');
  } catch (e) {
    Msg.message('修改价格失败', 'error');
  } finally {
    state.loading = false;
  }
};

const handleShowMsgbox = () => {
  state.msgDialog.title = '';
  state.msgDialog.content = '';
  state.msgDialog.seconds = 10;
  state.msgDialog.visible = true;
};

const confirmShowMsgbox = async () => {
  state.loading = true;
  try {
    await api('showMsgbox', {
      title: state.msgDialog.title,
      content: state.msgDialog.content,
      seconds: state.msgDialog.seconds,
    });
    state.msgDialog.visible = false;
    Msg.message('消息已发送', 'success');
  } catch (e) {
    Msg.message('发送消息失败', 'error');
  } finally {
    state.loading = false;
  }
};

const handleHideMsgbox = async () => {
  state.loading = true;
  try {
    await api('hideMsgbox');
    Msg.message('消息已清除', 'success');
  } catch (e) {
    Msg.message('清除消息失败', 'error');
  } finally {
    state.loading = false;
  }
};

const handleReboot = () => {
  Msg.confirm('确定要重启设备吗？重启有3-5秒延迟。').then(async () => {
    state.loading = true;
    try {
      await api('reboot');
      Msg.message('重启命令已发送', 'success');
    } catch (e) {
      Msg.message('重启失败', 'error');
    } finally {
      state.loading = false;
    }
  });
};

const handleForceCloseOrder = () => {
  Msg.confirm('确定要强制结算当前订单吗？此操作将立即关闭订单并释放设备。').then(async () => {
    state.loading = true;
    try {
      await api('forceCloseOrder');
      Msg.message('强制结算命令已发送', 'success');
      emit('refresh');
      setTimeout(() => loadDeviceState(), 2000);
    } catch (e) {
      Msg.message('强制结算失败', 'error');
    } finally {
      state.loading = false;
    }
  });
};

const fenToYuanConfig = (config: any) => {
  const c = { ...config };
  priceKeys.forEach(k => {
    if (c[k] != null) c[k] = parseFloat((c[k] / 100).toFixed(2));
  });
  return c;
};

const yuanToFenConfig = (config: any) => {
  const c = { ...config };
  priceKeys.forEach(k => {
    if (c[k] != null) c[k] = Math.round(c[k] * 100);
  });
  return c;
};

defineExpose({open});
</script>
