<script lang="ts" setup>
import { computed, reactive, ref, watch } from 'vue';

import { Page } from '@vben/common-ui';
import { useAccessStore } from '@vben/stores';

import {
  getBinanceRechargeConfig,
  saveBinanceRechargeConfig,
} from '#/api/legacy/pay';
import { getAllowedSysOrigins } from '#/views/system/shared';

import {
  Button,
  Card,
  Form,
  FormItem,
  Input,
  Select,
  Space,
  Switch,
  Table,
  Tag,
  message,
} from 'antdv-next';

defineOptions({ name: 'OperateBinanceRechargeConfig' });

let localRowId = 0;

function createRateRow(
  minAmount = '0',
  maxAmount = '0',
  goldPerUsd = '80000',
) {
  localRowId += 1;
  return {
    goldPerUsd,
    maxAmount,
    minAmount,
    rowKey: `binance-rate-${localRowId}`,
  };
}

const accessStore = useAccessStore();
const sysOriginOptions = computed(() => {
  const options = getAllowedSysOrigins(accessStore.accessCodes || []);
  return options.length > 0 ? options : getAllowedSysOrigins([]);
});

const selectedSysOrigin = ref('');
const loading = ref(false);
const saving = ref(false);
const form = reactive<Record<string, any>>({
  apiKey: '',
  apiSecret: '',
  apiSecretConfigured: false,
  enabled: true,
  rates: [createRateRow()],
  sysOrigin: '',
});

const rateColumns = [
  { dataIndex: 'minAmount', key: 'minAmount', title: '最小金额(含)', width: 180 },
  { dataIndex: 'maxAmount', key: 'maxAmount', title: '最大金额(不含)', width: 180 },
  { dataIndex: 'goldPerUsd', key: 'goldPerUsd', title: '1 USDT 对应金币', width: 200 },
  { dataIndex: 'actions', key: 'actions', title: '操作', width: 100 },
];

const statusMeta = computed(() => {
  if (!form.apiKey && !form.apiSecretConfigured) {
    return { color: 'default', text: '未配置' };
  }
  if (form.enabled) {
    return { color: 'success', text: '已启用' };
  }
  return { color: 'default', text: '已关闭' };
});

function normalizeDecimalText(value: unknown) {
  return String(value ?? '').trim();
}

function normalizeConfig(result: null | Record<string, any> | undefined) {
  const value = result || {};
  form.sysOrigin = String(value.sysOrigin || selectedSysOrigin.value || '');
  form.apiKey = String(value.apiKey || '');
  form.apiSecret = '';
  form.apiSecretConfigured = Boolean(value.apiSecretConfigured);
  form.enabled = value.enabled !== false;
  const rates = Array.isArray(value.rates) && value.rates.length > 0
    ? value.rates
    : [createRateRow('0', '100', '80000'), createRateRow('100', '0', '82000')];
  form.rates = rates.map((item: Record<string, any>) => ({
    goldPerUsd: String(item.goldPerUsd ?? '80000'),
    maxAmount: String(item.maxAmount ?? '0'),
    minAmount: String(item.minAmount ?? '0'),
    rowKey: item.rowKey || createRateRow().rowKey,
  }));
}

async function loadConfig() {
  if (!selectedSysOrigin.value) {
    return;
  }
  loading.value = true;
  try {
    const result = await getBinanceRechargeConfig(selectedSysOrigin.value);
    normalizeConfig(result);
  } finally {
    loading.value = false;
  }
}

function addRateRow() {
  const rows = form.rates as Array<Record<string, any>>;
  const last = rows.at(-1);
  const nextMin = Number(last?.maxAmount || last?.minAmount || 0);
  rows.push(createRateRow(String(Number.isFinite(nextMin) ? nextMin : 0), '0', '80000'));
}

function removeRateRow(index: number) {
  (form.rates as Array<Record<string, any>>).splice(index, 1);
}

function validateDecimal(value: unknown) {
  const text = normalizeDecimalText(value);
  if (!text) {
    return false;
  }
  const numeric = Number(text);
  return Number.isFinite(numeric);
}

function validateBeforeSave() {
  if (!selectedSysOrigin.value) {
    message.warning('请选择系统');
    return false;
  }
  if (!String(form.apiKey || '').trim()) {
    message.warning('请输入 API Key');
    return false;
  }
  if (!form.apiSecretConfigured && !String(form.apiSecret || '').trim()) {
    message.warning('请输入 API 秘钥');
    return false;
  }
  const rows = form.rates as Array<Record<string, any>>;
  if (rows.length === 0) {
    message.warning('请至少配置一个发金币区间');
    return false;
  }
  const normalized = rows.map((item) => ({
    goldPerUsd: normalizeDecimalText(item.goldPerUsd),
    maxAmount: normalizeDecimalText(item.maxAmount || '0'),
    minAmount: normalizeDecimalText(item.minAmount),
  }));
  for (const item of normalized) {
    if (
      !validateDecimal(item.minAmount) ||
      !validateDecimal(item.maxAmount) ||
      !validateDecimal(item.goldPerUsd)
    ) {
      message.warning('金额和金币比例必须是数字');
      return false;
    }
    const minAmount = Number(item.minAmount);
    const maxAmount = Number(item.maxAmount);
    const goldPerUsd = Number(item.goldPerUsd);
    if (minAmount < 0 || maxAmount < 0) {
      message.warning('金额区间不能小于 0');
      return false;
    }
    if (maxAmount > 0 && maxAmount <= minAmount) {
      message.warning('最大金额必须大于最小金额，或填 0 表示不限制');
      return false;
    }
    if (goldPerUsd <= 0) {
      message.warning('金币比例必须大于 0');
      return false;
    }
  }
  const sorted = [...normalized].sort(
    (left, right) => Number(left.minAmount) - Number(right.minAmount),
  );
  for (let index = 0; index < sorted.length; index += 1) {
    const current = sorted[index];
    const next = sorted[index + 1];
    const currentMax = Number(current?.maxAmount || 0);
    if (currentMax === 0 && index !== sorted.length - 1) {
      message.warning('不限制最大金额的区间必须放在最后');
      return false;
    }
    if (next && currentMax > Number(next.minAmount)) {
      message.warning('发金币区间不能重叠');
      return false;
    }
  }
  return true;
}

async function submitForm() {
  if (!validateBeforeSave()) {
    return;
  }
  saving.value = true;
  try {
    await saveBinanceRechargeConfig({
      apiKey: String(form.apiKey || '').trim(),
      apiSecret: String(form.apiSecret || '').trim(),
      enabled: Boolean(form.enabled),
      rates: (form.rates as Array<Record<string, any>>).map((item) => ({
        goldPerUsd: normalizeDecimalText(item.goldPerUsd),
        maxAmount: normalizeDecimalText(item.maxAmount || '0'),
        minAmount: normalizeDecimalText(item.minAmount),
      })),
      sysOrigin: selectedSysOrigin.value,
    });
    message.success('保存成功');
    await loadConfig();
  } finally {
    saving.value = false;
  }
}

watch(
  sysOriginOptions,
  (options) => {
    if (!selectedSysOrigin.value) {
      selectedSysOrigin.value = String(options[0]?.value || '');
    }
  },
  { immediate: true },
);

watch(
  selectedSysOrigin,
  (value) => {
    if (value) {
      void loadConfig();
    }
  },
  { immediate: true },
);
</script>

<template>
  <Page auto-content-height>
    <Card :bordered="false" title="币安配置">
      <div class="toolbar">
        <Select
          v-model:value="selectedSysOrigin"
          :options="sysOriginOptions"
          option-filter-prop="label"
          option-label-prop="label"
          placeholder="请选择系统"
          show-search
          style="width: 180px"
        />
        <Tag :color="statusMeta.color">{{ statusMeta.text }}</Tag>
        <Button :loading="loading" @click="loadConfig">刷新</Button>
      </div>

      <Form layout="vertical">
        <div class="form-grid">
          <FormItem label="启用自动充值验证">
            <Switch v-model:checked="form.enabled" />
          </FormItem>
          <FormItem label="API Key">
            <Input
              v-model:value="form.apiKey"
              allow-clear
              placeholder="请输入 Binance API Key"
            />
          </FormItem>
          <FormItem label="API 秘钥">
            <Input
              v-model:value="form.apiSecret"
              allow-clear
              :placeholder="form.apiSecretConfigured ? '留空则不修改已保存秘钥' : '请输入 Binance API 秘钥'"
              type="password"
            />
          </FormItem>
        </div>
      </Form>

      <div class="section-head">
        <div class="section-title">发金币区间</div>
        <Space>
          <Button @click="addRateRow">新增区间</Button>
          <Button :loading="saving" type="primary" @click="submitForm">保存配置</Button>
        </Space>
      </div>

      <Table
        :columns="rateColumns"
        :data-source="form.rates"
        :loading="loading"
        :pagination="false"
        row-key="rowKey"
        :scroll="{ x: 760 }"
      >
        <template #bodyCell="{ column, index, record }">
          <template v-if="column.key === 'minAmount'">
            <Input
              v-model:value="record.minAmount"
              placeholder="0"
              style="width: 140px"
            />
          </template>
          <template v-else-if="column.key === 'maxAmount'">
            <Input
              v-model:value="record.maxAmount"
              placeholder="0 表示不限制"
              style="width: 140px"
            />
          </template>
          <template v-else-if="column.key === 'goldPerUsd'">
            <Input
              v-model:value="record.goldPerUsd"
              placeholder="80000"
              style="width: 160px"
            />
          </template>
          <template v-else-if="column.key === 'actions'">
            <Button danger type="link" @click="removeRateRow(index)">删除</Button>
          </template>
        </template>
      </Table>
    </Card>
  </Page>
</template>

<style scoped>
.toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
  margin-bottom: 20px;
}

.form-grid {
  display: grid;
  grid-template-columns: minmax(160px, 220px) minmax(240px, 1fr) minmax(240px, 1fr);
  gap: 16px;
}

.section-head {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
  justify-content: space-between;
  margin: 8px 0 12px;
}

.section-title {
  font-size: 15px;
  font-weight: 600;
}

@media (max-width: 900px) {
  .form-grid {
    grid-template-columns: 1fr;
  }
}
</style>
