<template>
  <!-- ═══ 连接管理 ═══ -->
  <section class="panel">
    <div class="panel-header">
      <div class="panel-title-group">
        <h2>{{ $t('settings.panelConnection') }}</h2>
        <span class="experimental-badge">{{ $t('settings.experimentalBadge') }}</span>
      </div>
      <button class="btn btn-ghost btn-sm" @click="openConnForm()">{{ $t('settings.addConnection') }}</button>
    </div>
    <div class="connection-list" v-if="connections.length > 0">
      <div class="connection-card" v-for="conn in connections" :key="conn.id">
        <div class="conn-left">
          <span class="conn-icon">{{ typeIcon(conn.type) }}</span>
          <div class="conn-info">
            <div class="conn-name-row">
              <span class="conn-name">{{ conn.name }}</span>
              <span class="conn-type" :class="'type-' + conn.type">{{ typeLabel(conn.type) }}</span>
            </div>
            <span class="conn-host">{{ conn.host }}{{ conn.port ? ':' + conn.port : '' }}</span>
            <span class="conn-user" v-if="conn.user">{{ conn.user }}</span>
          </div>
        </div>
        <div class="conn-actions">
          <button class="btn-link" @click="openConnForm(conn)">{{ $t('common.edit') }}</button>
          <button class="btn-link btn-link-danger" @click="removeConn(conn.id)">{{ $t('common.delete') }}</button>
        </div>
      </div>
    </div>
    <div class="empty-hint" v-else>{{ $t('settings.emptyConnection') }}</div>
  </section>

  <!-- ═══ 连接表单 ═══ -->
  <section class="panel" v-if="connForm.visible">
    <div class="panel-header">
      <h2>{{ connForm.editId ? $t('settings.editConnectionTitle') : $t('settings.addConnectionTitle') }}</h2>
      <button class="btn btn-ghost btn-sm" @click="connForm.visible = false">{{ $t('common.cancel') }}</button>
    </div>
    <div class="form-grid">
      <div class="form-field">
        <label class="form-label">{{ $t('settings.labelName') }}</label>
        <input v-model="connForm.name" class="setting-input" :placeholder="$t('settings.phConnName')" />
      </div>
      <div class="form-field">
        <label class="form-label">{{ $t('settings.labelType') }}</label>
        <select v-model="connForm.type" class="setting-select" @change="onTypeChange">
          <option value="mysql">MySQL</option>
          <option value="ssh">SSH</option>
          <option value="redis">Redis</option>
          <option value="mongo">MongoDB</option>
        </select>
      </div>
      <!-- host + port 同一行(端口跟在 host 后面,符合 host:port 地址习惯) -->
      <div class="form-row">
        <div class="form-field form-field--host">
          <label class="form-label">{{ $t('settings.labelHost') }}</label>
          <input v-model="connForm.host" class="setting-input" :placeholder="$t('settings.phHost')" />
        </div>
        <div class="form-field form-field--port">
          <label class="form-label">{{ $t('settings.labelPort') }}</label>
          <input v-model.number="connForm.port" class="setting-number" type="number" min="1" max="65535" :placeholder="$t('settings.phPort')" />
        </div>
      </div>
      <div class="form-field">
        <label class="form-label">{{ $t('settings.labelUser') }}</label>
        <input v-model="connForm.user" class="setting-input" :placeholder="$t('settings.phUser')" />
      </div>
      <div class="form-field">
        <label class="form-label">{{ $t('settings.labelPassword') }}</label>
        <input v-model="connForm.password" class="setting-input" type="password" :placeholder="$t('settings.phPassword')" autocomplete="new-password" />
      </div>
      <div class="form-actions">
        <button class="btn btn-primary" :disabled="submitting" @click="saveConn">{{ $t('common.save') }}</button>
      </div>
    </div>
  </section>
</template>

<script setup lang="ts">
import { reactive, ref, onMounted } from 'vue'
import { useI18n } from 'vue-i18n'
import { useAppSettingsStore } from '@/stores/appSettings'

// ============================================================
// 连接管理域 — localStorage CRUD
// ============================================================
const { t } = useI18n()
const appSettings = useAppSettingsStore()

const emit = defineEmits<{
  // P0-2: 对齐 ToastType 加 'success'(本面板暂未用,保类型一致)
  (e: 'toast', msg: string, type: 'error' | 'warning' | 'info' | 'success'): void
}>()

const props = defineProps<{
  confirmDialog: (msg: string) => Promise<boolean>
}>()

interface ConnRecord {
  id: string
  name: string
  type: string
  host: string
  port: number
  user: string
  password: string
}

const connections = ref<ConnRecord[]>([])

// 各类型连接的默认端口(用户切换类型时自动带入,单一来源)
const DEFAULT_PORTS: Record<string, number> = { mysql: 3306, ssh: 22, redis: 6379, mongo: 27017 }

const connForm = reactive({
  visible: false,
  editId: '' as string,
  name: '',
  type: 'mysql',
  host: '',
  port: DEFAULT_PORTS.mysql,
  user: '',
  password: '',
})

// 异步操作禁用态(防双击重复提交):saveConn 保存连接期间禁用按钮
const submitting = ref(false)

const CONN_STORAGE_KEY = 'df-connections'

function loadConnections() {
  const stored = appSettings.get<ConnRecord[] | null>(CONN_STORAGE_KEY, null)
  if (stored) connections.value = stored
}

function persistConnections() {
  void appSettings.set(CONN_STORAGE_KEY, connections.value)
}

function typeIcon(type: string) {
  const map: Record<string, string> = { mysql: '🗄️', ssh: '🔐', redis: '⚡', mongo: '🍃' }
  return map[type] || '🔗'
}

function typeLabel(type: string) {
  const map: Record<string, string> = { mysql: 'MySQL', ssh: 'SSH', redis: 'Redis', mongo: 'MongoDB' }
  return map[type] || type
}

function openConnForm(conn?: ConnRecord) {
  if (conn) {
    connForm.editId = conn.id
    connForm.name = conn.name
    connForm.type = conn.type
    connForm.host = conn.host
    connForm.port = conn.port
    connForm.user = conn.user
    connForm.password = conn.password ?? ''
  } else {
    connForm.editId = ''
    connForm.name = ''
    connForm.type = 'mysql'
    connForm.host = ''
    connForm.port = DEFAULT_PORTS[connForm.type] ?? 3306
    connForm.user = ''
    connForm.password = ''
  }
  connForm.visible = true
}

/** 用户手动切换连接类型时,端口自动重置为该类型默认端口。
 *  用 @change(仅用户交互触发)而非 watch:避免编辑已有连接回填类型时误覆盖已存端口。 */
function onTypeChange(): void {
  connForm.port = DEFAULT_PORTS[connForm.type] ?? 3306
}

function saveConn() {
  if (!connForm.name || !connForm.host) {
    emit('toast', t('settings.toastConnIncomplete'), 'warning')
    return
  }
  // L20: 端口范围校验(1-65535)。v-model.number 清空输入会得 NaN,一并拦截。
  const port = connForm.port
  if (!Number.isInteger(port) || port < 1 || port > 65535) {
    emit('toast', t('settings.toastConnPortInvalid'), 'warning')
    return
  }
  submitting.value = true
  try {
    const record: ConnRecord = {
      id: connForm.editId || Date.now().toString(36),
      name: connForm.name,
      type: connForm.type,
      host: connForm.host,
      port: connForm.port,
      user: connForm.user,
      password: connForm.password,
    }
    if (connForm.editId) {
      const idx = connections.value.findIndex(c => c.id === connForm.editId)
      if (idx >= 0) connections.value[idx] = record
    } else {
      connections.value.push(record)
    }
    persistConnections()
    connForm.visible = false
  } finally {
    submitting.value = false
  }
}

async function removeConn(id: string) {
  const c = connections.value.find(x => x.id === id)
  if (!await props.confirmDialog(t('settings.confirmDeleteConn', { name: c?.name || id }))) return
  connections.value = connections.value.filter(c => c.id !== id)
  persistConnections()
  emit('toast', t('settings.toastDeleted'), 'info')
}

/** 暴露给 shell(loadConnections 仍保留供外部主动刷新) */
defineExpose({ loadConnections })

// 阶段3 UX 重构:本面板改为 advanced 类懒挂载,不再由 Settings.vue onMounted 调用,
// 改为自身挂载时载入(localStorage 读,同步无网络)。
onMounted(loadConnections)
</script>

<style scoped>
/* 阶段1/3 UX 重构:panel/panel-header/empty-hint/btn 系列/setting-select/
   已迁移到 settings.css 全局。
   本 scoped 仅保留 ConnectionPanel 特有样式:connection-card/conn 系列/type 系列/form 系列/
   setting-input/btn-link 等。 */

/* ===== 链接按钮(本面板特有,未进全局) ===== */
.btn-link { background: none; border: none; color: var(--df-accent); font-size: 12px; cursor: pointer; padding: 2px 6px; }
.btn-link:hover { text-decoration: underline; }
.btn-link-danger { color: var(--df-danger); }

/* ===== 标题组(panel-header 内 标题+badge 一组,与右侧按钮 space-between) ===== */
.panel-title-group { display: flex; align-items: center; gap: 8px; }

/* badge"实验功能·暂未接入 AI"(阶段7:warning 色,沿用 default-badge/pool-badge 模式) */
.experimental-badge {
  font-size: 10px;
  padding: 1px 6px;
  border-radius: var(--df-radius-xs);
  background: var(--df-warning-bg);
  color: var(--df-warning);
  font-weight: 500;
  white-space: nowrap;
}

/* ===== 连接卡片 ===== */
.connection-list { display: flex; flex-direction: column; gap: 8px; }
.connection-card {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 14px;
  background: var(--df-bg);
  border: 0.5px solid var(--df-border);
  border-radius: var(--df-radius);
}
.conn-left { display: flex; align-items: center; gap: 10px; }
.conn-icon { font-size: 18px; }
.conn-info { display: flex; flex-direction: column; gap: 2px; }
.conn-name-row { display: flex; align-items: center; gap: 8px; }
.conn-name { font-size: 14px; font-weight: 500; color: var(--df-text); }
.conn-type {
  font-size: 10px;
  padding: 2px 6px;
  border-radius: var(--df-radius-sm);
  font-weight: 500;
}
.type-mysql { background: rgba(100,181,246,0.15); color: var(--df-info); }
.type-ssh { background: var(--df-accent-soft); color: var(--df-accent); }
.type-redis { background: rgba(255,107,107,0.15); color: var(--df-danger); }
.type-mongo { background: rgba(100,255,218,0.15); color: var(--df-success); }

.conn-host, .conn-user {
  font-size: 12px;
  color: var(--df-text-dim);
  font-family: var(--df-font-mono);
}
.conn-user {
  background: rgba(90,99,128,0.2);
  padding: 1px 6px;
  border-radius: var(--df-radius-sm);
}
.conn-actions { display: flex; gap: 4px; }

/* 表单(本面板特有输入控件样式;.setting-select 走全局) */
.form-grid { display: flex; flex-direction: column; gap: 14px; }
.form-field { display: flex; flex-direction: row; align-items: center; gap: 10px; }
.form-label { flex: 0 0 44px; font-size: 12px; font-weight: 500; color: var(--df-text-secondary); text-align: right; }
.form-actions { display: flex; justify-content: flex-end; padding-top: 4px; }

.setting-input { flex: 1; min-width: 0; padding: 6px 12px; background: var(--df-bg); border: 0.5px solid var(--df-border); border-radius: var(--df-radius-sm); color: var(--df-text); font-size: 13px; outline: none; }
.setting-input:focus { border-color: var(--df-accent); }
.form-field .setting-select { flex: 1; min-width: 0; }
/* host+port 组合行(端口跟在 host 后;min-width:0 允许收缩防窄面板溢出,label 已缩窄控制距离) */
.form-row { display: flex; gap: 6px; }
.form-row .form-field { min-width: 0; }
.form-row .form-field--host { flex: 3; }
.form-row .form-field--port { flex: 2; }
/* port 数字框复用 .setting-number(隐藏原生箭头);在 form-row 内覆盖 flex 填满列宽 */
.form-row .setting-number { flex: 1; min-width: 0; }
</style>
