<script setup>
import { ref, reactive, computed, watch, onMounted } from 'vue'
import {
  NModal, NForm, NFormItem, NInput, NSelect, NButton, NIcon, NSpin
} from 'naive-ui'
import { CloseOutline, CheckmarkCircleOutline, AlertCircleOutline } from '@vicons/ionicons5'
import { createDataSource, updateDataSource, testDataSource } from '../../api/datasource'

const props = defineProps({
  show: { type: Boolean, default: false },
  /** null 表示新增；非空表示编辑 */
  editing: { type: Object, default: null }
})
const emit = defineEmits(['update:show', 'saved'])

const visible = computed({
  get: () => props.show,
  set: v => emit('update:show', v)
})

const form = reactive({
  id: null,
  name: '',
  type: 'MYSQL',
  jdbcUrl: '',
  username: '',
  passwordPlain: '',
  schemaName: ''
})

const typeOptions = [
  { label: 'MySQL', value: 'MYSQL' },
  { label: 'PostgreSQL', value: 'POSTGRESQL' },
  { label: '达梦 DM8', value: 'DAMENG' },
  { label: 'SQLite', value: 'SQLITE' },
  { label: 'Oracle (按需启用驱动)', value: 'ORACLE' },
  { label: 'SQL Server (按需启用驱动)', value: 'SQLSERVER' },
  { label: 'H2 (内部测试)', value: 'H2' }
]

// 不同 DB 的默认 jdbc URL
const defaultJdbcUrls = {
  MYSQL: 'jdbc:mysql://localhost:3306/your_db?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true',
  POSTGRESQL: 'jdbc:postgresql://localhost:5432/your_db',
  DAMENG: 'jdbc:dm://localhost:5236?schema=SYSDBA',
  ORACLE: 'jdbc:oracle:thin:@localhost:1521:orcl',
  SQLSERVER: 'jdbc:sqlserver://localhost:1433;databaseName=your_db',
  SQLITE: 'jdbc:sqlite:/path/to/database.db',
  H2: 'jdbc:h2:mem:test'
}

const testing = ref(false)
const testResult = ref(null)  // {success, message}
const saving = ref(false)

watch(() => props.show, (v) => {
  if (v) {
    if (props.editing) {
      form.id = props.editing.id
      form.name = props.editing.name || ''
      form.type = props.editing.type || 'MYSQL'
      form.jdbcUrl = props.editing.jdbcUrl || ''
      form.username = props.editing.username || ''
      form.passwordPlain = ''  // 编辑时密码留空表示不修改
      form.schemaName = props.editing.schemaName || ''
    } else {
      Object.assign(form, {
        id: null, name: '', type: 'MYSQL',
        jdbcUrl: defaultJdbcUrls.MYSQL,
        username: 'root', passwordPlain: '', schemaName: ''
      })
    }
    testResult.value = null
  }
})

function onTypeChange(type) {
  // 类型变更时，如果 jdbcUrl 还是默认值，自动填新类型的默认 URL
  const isDefault = Object.values(defaultJdbcUrls).includes(form.jdbcUrl) || !form.jdbcUrl
  if (isDefault) {
    form.jdbcUrl = defaultJdbcUrls[type] || ''
  }
}

async function onTest() {
  if (!validateForm()) return
  testing.value = true
  testResult.value = null
  try {
    const res = await testDataSource(buildPayload())
    testResult.value = res.data
  } catch (e) {
    testResult.value = { success: false, message: e.message }
  } finally {
    testing.value = false
  }
}

async function onSave() {
  if (!validateForm()) return
  saving.value = true
  try {
    if (form.id) {
      await updateDataSource(form.id, buildPayload())
    } else {
      await createDataSource(buildPayload())
    }
    visible.value = false
    emit('saved')
  } catch (e) {
    // 全局拦截器已经弹消息，这里无需再处理
  } finally {
    saving.value = false
  }
}

function validateForm() {
  if (!form.name.trim()) return false
  if (!form.jdbcUrl.trim()) return false
  if (!form.username.trim()) return false
  if (!form.id && !form.passwordPlain) return false
  return true
}

function buildPayload() {
  return {
    name: form.name.trim(),
    type: form.type,
    jdbcUrl: form.jdbcUrl.trim(),
    username: form.username.trim(),
    passwordPlain: form.passwordPlain || null,
    schemaName: form.schemaName.trim() || null
  }
}
</script>

<template>
  <n-modal :show="visible" @update:show="visible = $event" preset="card" style="max-width: 560px; width: 90vw"
    :bordered="false" :mask-closable="false">
    <template #header>
      <div class="form-header">
        <span class="form-title">{{ form.id ? '编辑数据源' : '新增数据源' }}</span>
        <button class="icon-btn" @click="visible = false">
          <n-icon size="18">
            <CloseOutline />
          </n-icon>
        </button>
      </div>
    </template>

    <n-form label-placement="left" label-width="100" size="small">
      <n-form-item label="名称">
        <n-input v-model:value="form.name" placeholder="数据源名称（唯一）" />
      </n-form-item>
      <n-form-item label="类型">
        <n-select v-model:value="form.type" :options="typeOptions" @update:value="onTypeChange" />
      </n-form-item>
      <n-form-item label="JDBC URL">
        <n-input v-model:value="form.jdbcUrl" placeholder="jdbc:mysql://host:port/db" />
      </n-form-item>
      <n-form-item label="用户名">
        <n-input v-model:value="form.username" placeholder="数据库用户名" />
      </n-form-item>
      <n-form-item :label="form.id ? '新密码' : '密码'">
        <n-input v-model:value="form.passwordPlain" type="password" show-password-on="click"
          :placeholder="form.id ? '留空表示不修改' : '请输入密码'" />
      </n-form-item>
      <n-form-item label="Schema">
        <n-input v-model:value="form.schemaName" placeholder="可选，PG/Oracle 默认 schema" />
      </n-form-item>
    </n-form>

    <div class="test-result" v-if="testResult">
      <div class="result-line" :class="{ success: testResult.success, error: !testResult.success }">
        <n-icon size="14">
          <CheckmarkCircleOutline v-if="testResult.success" />
          <AlertCircleOutline v-else />
        </n-icon>
        <span>{{ testResult.success ? '连接成功' : '连接失败' }}</span>
      </div>
      <div class="result-message" v-if="!testResult.success && testResult.message">
        {{ testResult.message }}
      </div>
    </div>

    <template #footer>
      <div class="form-footer">
        <n-button size="small" :loading="testing" @click="onTest">
          <template #icon v-if="testing"><n-spin size="14" /></template>
          测试连接
        </n-button>
        <div class="footer-right">
          <n-button size="small" @click="visible = false">取消</n-button>
          <n-button size="small" type="primary" :loading="saving" :disabled="!validateForm()" @click="onSave">
            {{ form.id ? '保存' : '创建' }}
          </n-button>
        </div>
      </div>
    </template>
  </n-modal>
</template>

<style scoped>
.form-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-right: 8px;
}

.form-title {
  font-size: 16px;
  font-weight: 600;
  color: var(--text-primary);
}

.icon-btn {
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  color: var(--text-secondary);
  cursor: pointer;
  border-radius: 6px;
}

.icon-btn:hover {
  color: var(--text-primary);
  background: rgba(255, 255, 255, 0.08);
}

.test-result {
  margin-top: 8px;
  padding: 10px 12px;
  border-radius: 6px;
  background: var(--bg-card);
  border: 1px solid var(--border-color);
}

.result-line {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  font-weight: 500;
}

.result-line.success {
  color: #10b981;
}

.result-line.error {
  color: #ef4444;
}

.result-message {
  margin-top: 6px;
  font-size: 12px;
  color: var(--text-secondary);
  font-family: monospace;
  word-break: break-all;
}

.form-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.footer-right {
  display: flex;
  gap: 8px;
}
</style>
