<script setup lang="ts">
import { ElMessage, ElMessageBox } from 'element-plus'
import { computed, onMounted, ref } from 'vue'
import { Plus, Refresh, View, Edit, Delete, Download, Upload, StarFilled } from '@element-plus/icons-vue'

import {
  fetchPaymentConfigs,
  deletePaymentConfig,
  exportPaymentConfigBackup,
  importPaymentConfigBackup,
  type PaymentConfig,
} from '@/features/admin/api/paymentConfig'
import { formatDateTime } from '@/shared/utils/time'
import { formatCent } from '@/shared/utils/money'
import { readError } from '@/shared/utils/error'
import PaymentConfigDialog from '../components/PaymentConfigDialog.vue'

const loading = ref(false)
const configs = ref<PaymentConfig[]>([])
const total = ref(0)
const currentPage = ref(1)
const pageSize = ref(20)
const exporting = ref(false)
const importing = ref(false)
const backupFileInput = ref<HTMLInputElement | null>(null)

const dialogVisible = ref(false)
const dialogMode = ref<'create' | 'edit' | 'view'>('create')
const currentConfig = ref<PaymentConfig | null>(null)

const filterProvider = ref('')
const filterPayWay = ref('')
const filterStatus = ref('')
const filterEnvironment = ref('')

const providerOptions = [
  { label: '全部', value: '' },
  { label: '乐刷支付', value: 'leshua' },
  { label: '拉卡拉支付', value: 'lakala' },
  { label: '顺成支付', value: 'shuncheng' },
  { label: '模拟支付', value: 'mock' },
]

const statusOptions = [
  { label: '全部', value: '' },
  { label: '启用', value: 'active' },
  { label: '禁用', value: 'disabled' },
  { label: '测试中', value: 'testing' },
]

const payWayOptions = [
  { label: '全部', value: '' },
  { label: '支付宝', value: 'ZFBZF' },
  { label: '微信', value: 'WXZF' },
]

const environmentOptions = [
  { label: '全部', value: '' },
  { label: '生产环境', value: 'production' },
  { label: '测试环境', value: 'sandbox' },
]

const filteredConfigs = computed(() => {
  return configs.value
})

onMounted(() => {
  loadConfigs()
})

async function loadConfigs() {
  loading.value = true
  try {
    const res = await fetchPaymentConfigs({
      provider: filterProvider.value || undefined,
      pay_way: filterPayWay.value || undefined,
      status: filterStatus.value || undefined,
      environment: filterEnvironment.value || undefined,
      page: currentPage.value,
      page_size: pageSize.value,
    })
    configs.value = res.items
    total.value = res.total
  } catch (error) {
    ElMessage.error(readError(error, '加载配置失败'))
  } finally {
    loading.value = false
  }
}

function handleCreate() {
  currentConfig.value = null
  dialogMode.value = 'create'
  dialogVisible.value = true
}

function handleView(row: PaymentConfig) {
  currentConfig.value = row
  dialogMode.value = 'view'
  dialogVisible.value = true
}

function handleEdit(row: PaymentConfig) {
  currentConfig.value = row
  dialogMode.value = 'edit'
  dialogVisible.value = true
}

async function handleDelete(row: PaymentConfig) {
  if (!canDeleteConfig(row)) {
    ElMessage.warning('该配置已有交易记录，需要保留用于退款、查询和回调验签')
    return
  }
  try {
    await ElMessageBox.confirm(`确定要删除配置"${row.name}"吗？`, '确认删除', {
      type: 'warning',
    })
    await deletePaymentConfig(row.id)
    ElMessage.success('删除成功')
    loadConfigs()
  } catch (error: any) {
    if (error !== 'cancel') {
      ElMessage.error(readError(error, '删除失败'))
    }
  }
}

async function handleExportBackup() {
  try {
    await ElMessageBox.confirm(
      '备份文件会包含支付密钥明文，请妥善保管。确定导出吗？',
      '导出支付配置备份',
      {
        type: 'warning',
        confirmButtonText: '导出',
        cancelButtonText: '取消',
      }
    )

    exporting.value = true
    const { blob, filename } = await exportPaymentConfigBackup()
    downloadBlob(blob, filename)
    ElMessage.success('导出成功')
  } catch (error: any) {
    if (error !== 'cancel') {
      ElMessage.error(readError(error, '导出备份失败'))
    }
  } finally {
    exporting.value = false
  }
}

function handleImportBackup() {
  backupFileInput.value?.click()
}

async function handleImportFile(event: Event) {
  const input = event.target as HTMLInputElement
  const file = input.files?.[0]
  input.value = ''
  if (!file) return

  let backup: unknown
  try {
    backup = JSON.parse(await file.text())
  } catch {
    ElMessage.error('备份文件不是有效的 JSON')
    return
  }

  try {
    await ElMessageBox.confirm(
      '导入会按服务商、商户号和支付方式新增或更新配置，并恢复备份中的启用配置。备份文件包含支付密钥明文，请确认来源可信。',
      '导入支付配置备份',
      {
        type: 'warning',
        confirmButtonText: '导入',
        cancelButtonText: '取消',
      }
    )

    importing.value = true
    const result = await importPaymentConfigBackup(backup)
    ElMessage.success(`导入成功：新增 ${result.created} 个，更新 ${result.updated} 个`)
    await loadConfigs()
  } catch (error: any) {
    if (error !== 'cancel' && error !== 'close') {
      ElMessage.error(readError(error, '导入备份失败'))
    }
  } finally {
    importing.value = false
  }
}

function downloadBlob(blob: Blob, filename: string) {
  const url = URL.createObjectURL(blob)
  const link = document.createElement('a')
  link.href = url
  link.download = filename
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
  URL.revokeObjectURL(url)
}

function handleDialogClose() {
  dialogVisible.value = false
  currentConfig.value = null
}

function handleSaved() {
  dialogVisible.value = false
  loadConfigs()
}

function formatProvider(provider: string) {
  const map: Record<string, string> = {
    leshua: '乐刷支付',
    lakala: '拉卡拉支付',
    shuncheng: '顺成支付',
    mock: '模拟支付',
  }
  return map[provider] || provider
}

// formatPayWay 将支付方式编码展示为运营可读名称。
function formatPayWay(payWay: string) {
  const map: Record<string, string> = {
    ZFBZF: '支付宝',
    WXZF: '微信',
  }
  return map[payWay] || payWay || '-'
}

// getPayWayClass 按支付方式返回标签样式，避免与状态/环境标签混淆。
function getPayWayClass(payWay: string) {
  const map: Record<string, string> = {
    ZFBZF: 'pay-way-alipay',
    WXZF: 'pay-way-wechat',
  }
  return map[payWay] || 'pay-way-other'
}

function formatStatus(status: string) {
  const map: Record<string, string> = {
    active: '启用',
    disabled: '禁用',
    testing: '测试中',
  }
  return map[status] || status
}

function formatEnvironment(env: string) {
  const map: Record<string, string> = {
    production: '生产',
    sandbox: '测试',
  }
  return map[env] || env
}

function formatAmount(amountCent: number) {
  return formatCent(amountCent)
}

function getEnvironmentClass(env: string) {
  const map: Record<string, string> = {
    production: 'env-production',
    sandbox: 'env-sandbox',
  }
  return map[env] || 'env-other'
}

function getStatusClass(status: string) {
  const map: Record<string, string> = {
    active: 'config-active',
    disabled: 'config-disabled',
    testing: 'config-testing',
  }
  return map[status] || 'config-disabled'
}

function isDefaultConfig(row: PaymentConfig) {
  const value = row.is_default as unknown
  return value === true || value === 'true' || value === 1
}

function tableRowClassName({ row }: { row: PaymentConfig }) {
  return isDefaultConfig(row) ? 'payment-config-row-default' : ''
}

function canDeleteConfig(row: PaymentConfig) {
  return (row.reference_count || 0) <= 0
}

function deleteDisabledReason(row: PaymentConfig) {
  if (canDeleteConfig(row)) return '删除配置'
  return `已有 ${row.reference_count || 0} 条支付记录引用，需要保留用于退款、查询和回调验签`
}
</script>

<template>
  <section class="page">
    <div class="page-header">
      <p class="eyebrow">Payment Configs</p>
      <h1>支付配置管理</h1>
      <p>管理多个支付商户配置，支付宝和微信可分别启用默认渠道。</p>
    </div>

    <div class="filter-bar">
      <el-select
        v-model="filterProvider"
        placeholder="支付服务商"
        style="width: 150px"
        @change="loadConfigs"
      >
        <el-option
          v-for="opt in providerOptions"
          :key="opt.value"
          :label="opt.label"
          :value="opt.value"
        />
      </el-select>
      <el-select
        v-model="filterPayWay"
        placeholder="支付方式"
        style="width: 120px"
        @change="loadConfigs"
      >
        <el-option
          v-for="opt in payWayOptions"
          :key="opt.value"
          :label="opt.label"
          :value="opt.value"
        />
      </el-select>
      <el-select
        v-model="filterStatus"
        placeholder="状态"
        style="width: 120px"
        @change="loadConfigs"
      >
        <el-option
          v-for="opt in statusOptions"
          :key="opt.value"
          :label="opt.label"
          :value="opt.value"
        />
      </el-select>
      <el-select
        v-model="filterEnvironment"
        placeholder="环境"
        style="width: 120px"
        @change="loadConfigs"
      >
        <el-option
          v-for="opt in environmentOptions"
          :key="opt.value"
          :label="opt.label"
          :value="opt.value"
        />
      </el-select>
      <el-button :icon="Refresh" @click="loadConfigs">刷新</el-button>
      <el-button :icon="Upload" :loading="importing" @click="handleImportBackup"
        >导入备份</el-button
      >
      <el-button :icon="Download" :loading="exporting" @click="handleExportBackup"
        >导出备份</el-button
      >
      <el-button type="primary" :icon="Plus" @click="handleCreate">新增配置</el-button>
    </div>

    <input
      ref="backupFileInput"
      class="backup-file-input"
      type="file"
      accept="application/json,.json"
      @change="handleImportFile"
    />

    <el-table
      :data="filteredConfigs"
      v-loading="loading"
      class="payment-config-table"
      :row-class-name="tableRowClassName"
      stripe
    >
      <el-table-column prop="name" label="配置名称" min-width="220" show-overflow-tooltip />
      <el-table-column prop="provider" label="服务商" width="120">
        <template #default="{ row }">
          {{ formatProvider(row.provider) }}
        </template>
      </el-table-column>
      <el-table-column prop="pay_way" label="支付方式" width="104" align="center">
        <template #default="{ row }">
          <el-tag class="config-tag" :class="getPayWayClass(row.pay_way)" size="small">
            {{ formatPayWay(row.pay_way) }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column prop="merchant_id" label="商户号" min-width="150" />
      <el-table-column prop="environment" label="环境" width="86" align="center">
        <template #default="{ row }">
          <el-tag class="config-tag" :class="getEnvironmentClass(row.environment)" size="small">
            {{ formatEnvironment(row.environment) }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column prop="status" label="状态" width="86" align="center">
        <template #default="{ row }">
          <el-tag class="config-tag" :class="getStatusClass(row.status)" size="small">
            {{ formatStatus(row.status) }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column prop="is_default" label="默认渠道" width="118" align="center">
        <template #default="{ row }">
          <span v-if="isDefaultConfig(row)" class="default-badge">
            <el-icon><StarFilled /></el-icon>
            默认渠道
          </span>
          <span v-else class="standby-badge">备用</span>
        </template>
      </el-table-column>
      <el-table-column label="支付记录" min-width="150">
        <template #default="{ row }">
          <div class="usage-cell">
            <div>成功: {{ row.total_transactions }} 笔</div>
            <div :class="{ 'usage-reference-locked': (row.reference_count || 0) > 0 }">
              引用: {{ row.reference_count || 0 }} 条
            </div>
            <div>金额: ¥{{ formatAmount(row.total_amount_cent) }}</div>
          </div>
        </template>
      </el-table-column>
      <el-table-column prop="last_used_at" label="最后成功支付" min-width="180" show-overflow-tooltip>
        <template #default="{ row }">
          {{ row.last_used_at ? formatDateTime(row.last_used_at, '-') : '-' }}
        </template>
      </el-table-column>
      <el-table-column label="操作" width="226" class-name="operation-column">
        <template #default="{ row }">
          <div class="action-buttons">
            <el-button
              class="action-button view"
              size="small"
              :icon="View"
              @click="handleView(row)"
            >
              查看
            </el-button>
            <el-button
              class="action-button edit"
              size="small"
              :icon="Edit"
              @click="handleEdit(row)"
            >
              编辑
            </el-button>
            <el-tooltip :content="deleteDisabledReason(row)" placement="top">
              <span>
                <el-button
                  class="action-button delete"
                  size="small"
                  :icon="Delete"
                  :disabled="!canDeleteConfig(row)"
                  @click="handleDelete(row)"
                >
                  删除
                </el-button>
              </span>
            </el-tooltip>
          </div>
        </template>
      </el-table-column>
    </el-table>

    <div class="pagination">
      <el-pagination
        v-model:current-page="currentPage"
        v-model:page-size="pageSize"
        :total="total"
        :page-sizes="[10, 20, 50, 100]"
        layout="total, sizes, prev, pager, next, jumper"
        @current-change="loadConfigs"
        @size-change="loadConfigs"
      />
    </div>

    <PaymentConfigDialog
      v-model="dialogVisible"
      :mode="dialogMode"
      :config="currentConfig"
      @close="handleDialogClose"
      @saved="handleSaved"
    />
  </section>
</template>

<style scoped>
.page {
  padding: 24px;
}

.page-header {
  margin-bottom: 24px;
}

.page-header .eyebrow {
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: #6b7280;
  margin-bottom: 8px;
}

.page-header h1 {
  font-size: 24px;
  font-weight: 600;
  margin: 0 0 8px 0;
}

.page-header p {
  color: #6b7280;
  margin: 0;
}

.filter-bar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: 16px;
}

.backup-file-input {
  display: none;
}

.payment-config-table {
  width: 100%;
  border-radius: 0;
}

.payment-config-table :deep(.el-table__cell) {
  padding: 11px 0;
}

.payment-config-table :deep(.cell) {
  padding: 0 14px;
  line-height: 1.45;
}

.payment-config-table :deep(th.el-table__cell) {
  background: #ffffff;
  color: #737b8b;
  font-weight: 600;
}

.payment-config-table :deep(.payment-config-row-default td.el-table__cell) {
  background: #f8fbff;
}

.payment-config-table :deep(.payment-config-row-default td.el-table__cell:first-child) {
  box-shadow: inset 3px 0 0 #2563eb;
}

.config-tag {
  min-width: 46px;
  justify-content: center;
  border-radius: 5px;
  font-weight: 600;
}

.config-tag.pay-way-alipay {
  color: #1d4ed8;
  background: #eff6ff;
  border-color: #bfdbfe;
}

.config-tag.pay-way-wechat {
  color: #047857;
  background: #ecfdf5;
  border-color: #a7f3d0;
}

.config-tag.pay-way-other {
  color: #475569;
  background: #f8fafc;
  border-color: #cbd5e1;
}

.config-tag.env-production {
  color: #475569;
  background: #f8fafc;
  border-color: #cbd5e1;
}

.config-tag.env-sandbox {
  color: #92400e;
  background: #fffbeb;
  border-color: #fde68a;
}

.config-tag.env-other {
  color: #64748b;
  background: #f8fafc;
  border-color: #cbd5e1;
}

.config-tag.config-active {
  color: #075985;
  background: #e0f2fe;
  border-color: #7dd3fc;
}

.config-tag.config-disabled {
  color: #64748b;
  background: #f1f5f9;
  border-color: #cbd5e1;
}

.config-tag.config-testing {
  color: #92400e;
  background: #fffbeb;
  border-color: #fde68a;
}

.default-badge,
.standby-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 72px;
  height: 24px;
  border-radius: 6px;
  font-size: 12px;
  font-weight: 700;
  white-space: nowrap;
}

.default-badge {
  gap: 4px;
  color: #ffffff;
  background: #1d4ed8;
  box-shadow: 0 4px 10px rgb(29 78 216 / 0.16);
}

.default-badge .el-icon {
  font-size: 13px;
}

.standby-badge {
  color: #94a3b8;
  background: transparent;
  font-weight: 600;
}

.usage-cell {
  display: grid;
  gap: 4px;
  font-size: 12px;
  line-height: 1.35;
  color: #3f4654;
  white-space: nowrap;
}

.usage-reference-locked {
  color: #dc2626;
  font-weight: 600;
}

.action-buttons {
  display: flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}

.action-buttons :deep(.el-button + .el-button) {
  margin-left: 0;
}

.action-button {
  min-width: 54px;
  height: 28px;
  padding: 0 7px;
  border-radius: 6px;
  font-weight: 500;
}

.payment-config-table :deep(.operation-column .cell) {
  padding: 0 10px;
}

.action-button.view {
  color: #1d4ed8;
  background: #eff6ff;
  border-color: #bfdbfe;
}

.action-button.view:hover {
  color: #ffffff;
  background: #2563eb;
  border-color: #2563eb;
}

.action-button.edit {
  color: #047857;
  background: #ecfdf5;
  border-color: #a7f3d0;
}

.action-button.edit:hover {
  color: #ffffff;
  background: #059669;
  border-color: #059669;
}

.action-button.delete {
  color: #dc2626;
  background: #fef2f2;
  border-color: #fecaca;
}

.action-button.delete:hover {
  color: #ffffff;
  background: #dc2626;
  border-color: #dc2626;
}

.pagination {
  margin-top: 16px;
  display: flex;
  justify-content: flex-end;
}
</style>
