<script setup lang="ts">
import { computed, ref } from 'vue'
import { getConfig, setConfig } from '@/config'
import { useAiChat } from '@/composables/useAiChat'

/**
 * 设置页(连接配置查看/编辑 + 连接状态 + 连接操作)。
 *
 * 默认查看模式(只读展示 relayHost/deviceId/token,token 脱敏);点「编辑」进入编辑模式,
 * 保存时 setConfig 持久化并 resumeIfDisconnected 用新配置重连。连接态可「断开」,
 * 断开态可「重连」,另展示最近状态详情(wsStatusDetail)辅助排查。
 *
 * 数据源:
 * - 连接配置:config.ts getConfig()(storage 持久化,含默认值合并)
 * - 连接状态:useAiChat() 单例(wsStatus + deviceOnline,实时)
 * - 版本号:manifest.json versionName(手动维护此处常量,对齐 0.1.0)
 */

// 连接配置(只读快照,页面 onShow 时刷新,切 tab 回来看最新值)
const cfg = computed(() => getConfig())

// 连接状态(实时,useAiChat 单例 ref 直接响应)
const ai = useAiChat()
const wsStatus = computed(() => ai.wsStatus.value)
const wsStatusDetail = computed(() => ai.wsStatusDetail.value)
const deviceOnline = computed(() => ai.deviceOnline.value)
const isWsConnected = computed(() => ai.isWsConnected.value)

/** 连接状态中文文案 + 颜色 class(对齐 chat 页 STATUS_TEXT 口径) */
const STATUS_META: Record<string, { label: string; cls: string }> = {
  connected: { label: '已连接', cls: 'st-ok' },
  connecting: { label: '连接中…', cls: 'st-wait' },
  handshaking: { label: '握手中…', cls: 'st-wait' },
  reconnecting: { label: '重连中…', cls: 'st-warn' },
  disconnected: { label: '已断开', cls: 'st-err' },
}
const statusText = computed(() => {
  if (isWsConnected.value) {
    return deviceOnline.value ? '已连接桌面端' : '已连接中继'
  }
  return STATUS_META[wsStatus.value]?.label || wsStatus.value
})
const statusCls = computed(() => {
  if (isWsConnected.value) return deviceOnline.value ? 'st-ok' : 'st-warn'
  return STATUS_META[wsStatus.value]?.cls || 'st-err'
})

/** token 脱敏(只显前 4 位 + 星号,查看页不暴露全量凭据) */
function maskToken(token: string): string {
  if (!token) return '(未设置)'
  if (token.length <= 8) return '*'.repeat(token.length)
  return `${token.slice(0, 4)}${'*'.repeat(Math.min(token.length - 4, 12))}`
}

/** 毫秒转可读(30000 → 30s) */
function fmtMs(ms: number): string {
  return ms >= 1000 ? `${ms / 1000}s` : `${ms}ms`
}

/** 版本号(对齐 manifest.json versionName,改版时同步) */
const APP_VERSION = '0.1.0'

/** 手动重连(断开态可点)。用 ai.connect() 而非 resumeIfDisconnected:
 *  用户先点「断开」(manualClose=true)后 resumeIfDisconnected 会因 manualClose 早退,
 *  connect() 复位 manualClose 强制开新连接(非连接态才生效,连接态自动幂等跳过)。 */
function onReconnect(): void {
  ai.connect()
}

/** 手动断开(连接态可点,disconnect 置 manualClose 后不再自动重连) */
function onDisconnect(): void {
  ai.disconnect()
  uni.showToast({ title: '已断开连接', icon: 'none' })
}

/** 连接操作按钮入口(连接态→断开,断开态→重连) */
function onConnOp(): void {
  if (isWsConnected.value) onDisconnect()
  else onReconnect()
}

/** 编辑态(false=查看模式,true=编辑模式;草稿保存时才 setConfig,取消丢弃) */
const editing = ref(false)
const draftRelayHost = ref('')
const draftDeviceId = ref('')
const draftToken = ref('')

/** 进入编辑模式:以当前配置填充草稿 */
function enterEdit(): void {
  draftRelayHost.value = cfg.value.relayHost
  draftDeviceId.value = cfg.value.deviceId
  draftToken.value = cfg.value.token
  editing.value = true
}

/** 取消编辑:丢弃草稿回查看模式(不保存) */
function cancelEdit(): void {
  editing.value = false
}

/** 保存编辑:setConfig 持久化 + 提示 + resumeIfDisconnected 用新配置重连 */
function saveEdit(): void {
  const relayHost = draftRelayHost.value.trim()
  const deviceId = draftDeviceId.value.trim()
  if (!relayHost || !deviceId) {
    uni.showToast({ title: '中继地址和设备 ID 不能为空', icon: 'none' })
    return
  }
  setConfig({ relayHost, deviceId, token: draftToken.value.trim() })
  editing.value = false
  uni.showToast({ title: '已保存,正在重连…', icon: 'none' })
  ai.resumeIfDisconnected()
}
</script>

<template>
  <view class="settings-page">
    <!-- 连接状态卡片(实时,断开可点重连) -->
    <view class="card">
      <view class="card-head">
        <text class="card-title">连接状态</text>
      </view>
      <view class="row">
        <text class="row-label">当前状态</text>
        <text class="row-value status" :class="statusCls" @tap="onReconnect">{{ statusText }}</text>
      </view>
      <view class="row">
        <text class="row-label">中继地址</text>
        <text class="row-value mono">{{ cfg.relayHost }}</text>
      </view>
      <view class="row" v-if="wsStatusDetail">
        <text class="row-label">最近状态</text>
        <text class="row-value">{{ wsStatusDetail }}</text>
      </view>
      <view class="ops">
        <view class="btn btn-block" :class="isWsConnected ? 'btn-danger' : 'btn-primary'" @tap="onConnOp">
          {{ isWsConnected ? '断开' : '重连' }}
        </view>
      </view>
    </view>

    <!-- 连接配置(查看/编辑双模式:编辑可改 relayHost/deviceId/token) -->
    <view class="card">
      <view class="card-head">
        <text class="card-title">连接配置</text>
        <view v-if="editing" class="card-actions">
          <text class="btn btn-sm btn-ghost" @tap="cancelEdit">取消</text>
          <text class="btn btn-sm btn-primary" @tap="saveEdit">保存</text>
        </view>
        <text v-else class="btn btn-sm btn-ghost" @tap="enterEdit">编辑</text>
      </view>
      <view class="row">
        <text class="row-label">中继地址</text>
        <input v-if="editing" v-model="draftRelayHost" class="row-input" placeholder="ws://…/ws/miniapp" placeholder-class="row-ph" />
        <text v-else class="row-value mono">{{ cfg.relayHost }}</text>
      </view>
      <view class="row">
        <text class="row-label">设备 ID</text>
        <input v-if="editing" v-model="draftDeviceId" class="row-input" placeholder="桌面端设备 ID" placeholder-class="row-ph" />
        <text v-else class="row-value mono">{{ cfg.deviceId }}</text>
      </view>
      <view class="row">
        <text class="row-label">配对 Token</text>
        <input v-if="editing" v-model="draftToken" class="row-input" placeholder="配对 token" placeholder-class="row-ph" />
        <text v-else class="row-value mono">{{ maskToken(cfg.token) }}</text>
      </view>
    </view>

    <!-- 高级参数 -->
    <view class="card">
      <view class="card-head">
        <text class="card-title">高级参数</text>
      </view>
      <view class="row">
        <text class="row-label">心跳间隔</text>
        <text class="row-value">{{ fmtMs(cfg.heartbeatInterval) }}</text>
      </view>
      <view class="row">
        <text class="row-label">重连初始间隔</text>
        <text class="row-value">{{ fmtMs(cfg.reconnectBaseDelay) }}</text>
      </view>
      <view class="row">
        <text class="row-label">重连最大间隔</text>
        <text class="row-value">{{ fmtMs(cfg.reconnectMaxDelay) }}</text>
      </view>
    </view>

    <!-- 关于 -->
    <view class="card">
      <view class="card-head">
        <text class="card-title">关于</text>
      </view>
      <view class="row">
        <text class="row-label">版本</text>
        <text class="row-value">DevFlow Mini v{{ APP_VERSION }}</text>
      </view>
      <view class="row">
        <text class="row-label">说明</text>
        <text class="row-value">远程 AI Chat · 跨端操作桌面端开发助手</text>
      </view>
    </view>
  </view>
</template>

<style lang="scss" scoped>
.settings-page {
  min-height: 100vh;
  padding: 24rpx;
  box-sizing: border-box;
  background-color: $uni-bg-color;
}
.card {
  margin-bottom: 24rpx;
  padding: 24rpx;
  background-color: $uni-bg-color-light;
  border-radius: 16rpx;
}
.card-head {
  display: flex;
  flex-direction: row;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 16rpx;
}
.card-title {
  font-size: $uni-font-size-base;
  font-weight: bold;
  color: $uni-text-color;
}
.card-sub {
  font-size: $uni-font-size-sm;
  color: $uni-text-color-disable;
}
.row {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  padding: 16rpx 0;
  border-bottom: 1rpx solid $uni-border-color;
}
.row:last-child {
  border-bottom: none;
}
.row-label {
  font-size: $uni-font-size-sm;
  color: $uni-text-color-grey;
}
.row-value {
  flex: 1;
  margin-left: 24rpx;
  font-size: $uni-font-size-sm;
  color: $uni-text-color;
  text-align: right;
  word-break: break-all;
}
.row-value.mono {
  font-family: monospace;
}
.row-value.status {
  font-weight: bold;
}
.st-ok { color: #6bd99a; }
.st-wait { color: $uni-color-primary; }
.st-warn { color: #f0c75e; }
.st-err { color: #e85a4f; }

/* 连接操作按钮(连接状态卡:重连/断开) */
.ops {
  margin-top: 8rpx;
}
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 8rpx 24rpx;
  font-size: $uni-font-size-sm;
  line-height: 1.6;
  border-radius: 10rpx;
}
.btn-block {
  display: block;
  padding: 20rpx 32rpx;
  text-align: center;
}
.btn-primary {
  background-color: $uni-color-primary;
  color: #fff;
}
.btn-danger {
  background-color: #e85a4f;
  color: #fff;
}
.btn-ghost {
  color: $uni-color-primary;
  border: 1rpx solid $uni-color-primary;
  background-color: transparent;
}
/* 卡片头部按钮组(编辑/取消/保存) */
.card-actions {
  display: flex;
  flex-direction: row;
  align-items: center;
}
.card-actions .btn {
  margin-left: 16rpx;
}
.btn-sm {
  padding: 4rpx 20rpx;
}
/* 编辑态输入(label 左 + input 右,横向一行对齐 .row-value) */
.row-input {
  flex: 1;
  margin-left: 24rpx;
  font-size: $uni-font-size-sm;
  color: $uni-text-color;
  text-align: right;
}
.row-ph {
  color: $uni-text-color-disable;
}
</style>
