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

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

import {
  Button,
  Card,
  Input,
  InputNumber,
  message,
  Modal,
  Select,
  Space,
  Spin,
  Switch,
  Table,
  TabPane,
  Tabs,
  Tag,
} from 'antdv-next';

import {
  getResidentFirstRechargeRewardConfig,
  pageResidentFirstRechargeRewardGrantRecords,
  saveResidentFirstRechargeRewardConfig,
} from '#/api/legacy/resident-activity';
import ActivityResourceGroupSelectDrawer from '#/views/props/components/activity-resource-group-select-drawer.vue';
import RewardRow from '#/views/props/components/reward-row.vue';
import { getAllowedSysOrigins } from '#/views/system/shared';

defineOptions({ name: 'ResidentFirstRechargeRewardConfigPage' });

let localRowId = 0;

function createRowKey(seed?: number | string) {
  localRowId += 1;
  return `first-recharge-reward-${seed || localRowId}-${localRowId}`;
}

function createLevel(level = 1, rechargeAmount = 10) {
  return {
    enabled: true,
    googleProductId: '',
    id: null,
    level,
    rechargeAmount,
    rechargeAmountCents: 0,
    rewardGroupId: null,
    rewardGroupName: '',
    rewardItems: [] as Array<Record<string, any>>,
    rowKey: createRowKey(),
  };
}

function normalizeID(value: unknown) {
  const text = String(value ?? '').trim();
  return text && text !== '0' ? text : '';
}

function hasPositiveID(value: unknown) {
  return /^\d+$/.test(normalizeID(value));
}

function defaultLevels() {
  return [createLevel(1, 10), createLevel(2, 50), createLevel(3, 100)];
}

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

const selectedSysOrigin = ref('');
const activeTab = ref('config');
const loading = ref(false);
const recordLoading = ref(false);
const saving = ref(false);
const groupPickerOpen = ref(false);
const pickerLevelIndex = ref(-1);

const form = reactive<Record<string, any>>({
  configured: false,
  enabled: false,
  id: 0,
  levelConfigs: defaultLevels(),
  minAppVersion: '',
  sysOrigin: '',
  updateTime: '',
});

const levelColumns = [
  { dataIndex: 'enabled', key: 'enabled', title: '启用', width: 90 },
  { dataIndex: 'level', key: 'level', title: '档位', width: 110 },
  { dataIndex: 'rechargeAmount', key: 'rechargeAmount', title: '首冲金额', width: 180 },
  { dataIndex: 'googleProductId', key: 'googleProductId', title: '谷歌商品ID', width: 240 },
  { dataIndex: 'rewardGroup', key: 'rewardGroup', title: '奖励资源组', width: 420 },
  { dataIndex: 'actions', key: 'actions', title: '操作', width: 100 },
];

const enabledLevelCount = computed(() =>
  (form.levelConfigs || []).filter((item: Record<string, any>) => item.enabled !== false).length,
);

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

const recordQuery = reactive<Record<string, any>>({
  cursor: 1,
  limit: 20,
  status: '',
  userId: '',
});

const recordPage = reactive<Record<string, any>>({
  current: 1,
  records: [],
  size: 20,
  total: 0,
});

const statusOptions = [
  { label: '全部状态', value: '' },
  { label: '发放中', value: 'PENDING' },
  { label: '已发放', value: 'SUCCESS' },
  { label: '发放失败', value: 'FAILED' },
];

const recordColumns = [
  { dataIndex: 'user', key: 'user', title: '用户', width: 260 },
  { dataIndex: 'rechargeAmount', key: 'rechargeAmount', title: '充值金额', width: 120 },
  { dataIndex: 'rechargeThreshold', key: 'rechargeThreshold', title: '达标金额', width: 120 },
  { dataIndex: 'level', key: 'level', title: '档位', width: 90 },
  { dataIndex: 'payPlatform', key: 'payPlatform', title: '充值方式', width: 180 },
  { dataIndex: 'sourceOrderId', key: 'sourceOrderId', title: '订单', width: 180 },
  { dataIndex: 'rewardGroup', key: 'rewardGroup', title: '奖励资源组', width: 360 },
  { dataIndex: 'status', key: 'status', title: '发放状态', width: 120 },
  { dataIndex: 'sentAt', key: 'sentAt', title: '发放时间', width: 180 },
  { dataIndex: 'lastError', key: 'lastError', title: '失败原因', width: 220 },
];

function toAmountCents(value: number | string | undefined) {
  const numeric = Number(value || 0);
  if (!Number.isFinite(numeric)) {
    return 0;
  }
  return Math.round(numeric * 100);
}

function formatAmount(value: number | string | undefined) {
  const numeric = Number(value || 0);
  return Number.isFinite(numeric) ? numeric.toFixed(2) : '0.00';
}

function normalizeConfig(result: null | Record<string, any> | undefined) {
  const value = result || {};
  form.configured = Boolean(value.configured);
  form.enabled = Boolean(value.enabled);
  form.id = value.id || 0;
  form.minAppVersion = String(value.minAppVersion || '');
  form.sysOrigin = String(value.sysOrigin || selectedSysOrigin.value || '');
  form.updateTime = String(value.updateTime || '');
  const levels = Array.isArray(value.levelConfigs) && value.levelConfigs.length > 0
    ? value.levelConfigs
    : defaultLevels();
  form.levelConfigs = levels
    .map((item: Record<string, any>, index: number) => {
      const rechargeAmount = Number(
        item.rechargeAmount ?? Number(item.rechargeAmountCents || 0) / 100,
      );
      return {
        enabled: item.enabled !== false,
        googleProductId: String(item.googleProductId || ''),
        id: item.id ?? null,
        level: Number(item.level || index + 1),
        rechargeAmount: Number.isFinite(rechargeAmount) ? rechargeAmount : 0,
        rechargeAmountCents: Number(item.rechargeAmountCents || 0),
        rewardGroupId: normalizeID(item.rewardGroupId) || null,
        rewardGroupName: String(item.rewardGroupName || ''),
        rewardItems: Array.isArray(item.rewardItems) ? item.rewardItems : [],
        rowKey: createRowKey(item.id || index),
      };
    })
    .toSorted((left: Record<string, any>, right: Record<string, any>) =>
      toAmountCents(left.rechargeAmount) - toAmountCents(right.rechargeAmount),
    );
}

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

function normalizeRecordPage(result: null | Record<string, any> | undefined) {
  const value = result || {};
  recordPage.records = Array.isArray(value.records) ? value.records : [];
  recordPage.total = Number(value.total || 0);
  recordPage.current = Number(value.current || 1);
  recordPage.size = Number(value.size || 20);
}

async function loadGrantRecords() {
  if (!selectedSysOrigin.value) {
    return;
  }
  recordLoading.value = true;
  try {
    const result = await pageResidentFirstRechargeRewardGrantRecords({
      ...recordQuery,
      sysOrigin: selectedSysOrigin.value,
    });
    normalizeRecordPage(result);
  } finally {
    recordLoading.value = false;
  }
}

function addLevel() {
  const levels = form.levelConfigs as Array<Record<string, any>>;
  const maxLevel = Math.max(0, ...levels.map((item) => Number(item.level || 0)));
  const maxAmount = Math.max(0, ...levels.map((item) => Number(item.rechargeAmount || 0)));
  levels.push(createLevel(maxLevel + 1, maxAmount + 10));
}

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

function confirmRemoveLevel(index: number) {
  Modal.confirm({
    onOk: () => removeLevel(index),
    title: '确认删除该首冲奖励档位？',
  });
}

function openRewardPicker(index: number) {
  pickerLevelIndex.value = index;
  groupPickerOpen.value = true;
}

function clearRewardGroup(record: Record<string, any>) {
  record.rewardGroupId = null;
  record.rewardGroupName = '';
  record.rewardItems = [];
}

function handleRewardGroupSelect(row: Record<string, any>) {
  const levels = form.levelConfigs as Array<Record<string, any>>;
  const target = levels[pickerLevelIndex.value];
  if (!target) {
    groupPickerOpen.value = false;
    return;
  }
  target.rewardGroupId = normalizeID(row.id) || null;
  target.rewardGroupName = String(row.name || '');
  target.rewardItems = Array.isArray(row.rewardConfigList) ? row.rewardConfigList : [];
  groupPickerOpen.value = false;
}

function validateBeforeSave() {
  const levels = form.levelConfigs as Array<Record<string, any>>;
  if (levels.length === 0) {
    message.warning('请至少配置一个首冲奖励档位');
    return false;
  }
  const seenLevels = new Set<string>();
  const seenAmounts = new Set<string>();
  const seenGoogleProductIds = new Set<string>();
  for (const item of levels) {
    const level = Number(item.level || 0);
    const amountCents = toAmountCents(item.rechargeAmount);
    if (level <= 0) {
      message.warning('档位必须大于 0');
      return false;
    }
    if (amountCents <= 0) {
      message.warning('首冲金额必须大于 0');
      return false;
    }
    if (!hasPositiveID(item.rewardGroupId)) {
      message.warning('每个档位都需要配置奖励资源组');
      return false;
    }
    if (seenLevels.has(String(level))) {
      message.warning('档位不能重复');
      return false;
    }
    if (seenAmounts.has(String(amountCents))) {
      message.warning('首冲金额不能重复');
      return false;
    }
    const googleProductId = String(item.googleProductId || '').trim();
    if (googleProductId) {
      if (seenGoogleProductIds.has(googleProductId)) {
        message.warning('谷歌商品ID不能重复');
        return false;
      }
      seenGoogleProductIds.add(googleProductId);
    }
    seenLevels.add(String(level));
    seenAmounts.add(String(amountCents));
  }
  if (form.enabled && enabledLevelCount.value === 0) {
    message.warning('启用配置时至少要启用一个首冲奖励档位');
    return false;
  }
  if (form.enabled && !String(form.minAppVersion || '').trim()) {
    message.warning('启用配置时需要填写最低App版本');
    return false;
  }
  return true;
}

async function submitForm() {
  if (!validateBeforeSave()) {
    return;
  }
  saving.value = true;
  try {
    await saveResidentFirstRechargeRewardConfig({
      enabled: Boolean(form.enabled),
      id: form.id || 0,
      levelConfigs: (form.levelConfigs || []).map((item: Record<string, any>) => ({
        enabled: item.enabled !== false,
        googleProductId: String(item.googleProductId || '').trim(),
        id: item.id || 0,
        level: Number(item.level || 0),
        rechargeAmount: formatAmount(item.rechargeAmount),
        rechargeAmountCents: toAmountCents(item.rechargeAmount),
        rewardGroupId: normalizeID(item.rewardGroupId) || null,
        rewardGroupName: String(item.rewardGroupName || ''),
      })),
      minAppVersion: String(form.minAppVersion || '').trim(),
      sysOrigin: selectedSysOrigin.value,
    });
    message.success('保存成功');
    await loadConfig();
    if (activeTab.value === 'records') {
      await loadGrantRecords();
    }
  } finally {
    saving.value = false;
  }
}

function searchGrantRecords() {
  recordQuery.cursor = 1;
  void loadGrantRecords();
}

function handleGrantTableChange(pagination: Record<string, any>) {
  recordQuery.cursor = Number(pagination.current || 1);
  recordQuery.limit = Number(pagination.pageSize || 20);
  void loadGrantRecords();
}

function avatarBackgroundStyle(url: string) {
  return {
    backgroundImage: `url("${String(url || '').replaceAll('"', '%22')}")`,
  };
}

function grantStatusMeta(status: string) {
  if (status === 'SUCCESS') {
    return { color: 'success', text: '已发放' };
  }
  if (status === 'FAILED') {
    return { color: 'error', text: '发放失败' };
  }
  return { color: 'processing', text: '发放中' };
}

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

watch(
  selectedSysOrigin,
  (value) => {
    if (value) {
      recordQuery.cursor = 1;
      void loadConfig();
      void loadGrantRecords();
    }
  },
  { immediate: true },
);

watch(activeTab, (value) => {
  if (value === 'records') {
    void loadGrantRecords();
  }
});
</script>

<template>
  <Page auto-content-height>
    <Spin :spinning="loading">
      <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>
          <Tag color="processing">仅 Google / 三方充值</Tag>
          <Button :loading="loading" @click="loadConfig">刷新</Button>
        </div>

        <Tabs v-model:active-key="activeTab">
          <TabPane key="config" tab="奖励配置">
            <div class="config-row">
              <Space align="center" wrap>
                <span class="field-label">启用</span>
                <Switch v-model:checked="form.enabled" />
                <span class="field-label">最低App版本</span>
                <Input
                  v-model:value="form.minAppVersion"
                  allow-clear
                  placeholder="例如 1.5.0"
                  style="width: 160px"
                />
                <span class="sub-text">更新时间：{{ form.updateTime || '-' }}</span>
              </Space>
            </div>

            <Table
              :columns="levelColumns"
              :data-source="form.levelConfigs"
              :loading="loading"
              :pagination="false"
              row-key="rowKey"
              :scroll="{ x: 1140 }"
            >
              <template #bodyCell="{ column, index, record }">
                <template v-if="column.key === 'enabled'">
                  <Switch v-model:checked="record.enabled" />
                </template>
                <template v-else-if="column.key === 'level'">
                  <InputNumber
                    v-model:value="record.level"
                    :min="1"
                    :precision="0"
                    style="width: 90px"
                  />
                </template>
                <template v-else-if="column.key === 'rechargeAmount'">
                  <InputNumber
                    v-model:value="record.rechargeAmount"
                    :min="0.01"
                    :precision="2"
                    style="width: 140px"
                  />
                </template>
                <template v-else-if="column.key === 'googleProductId'">
                  <Input
                    v-model:value="record.googleProductId"
                    allow-clear
                    placeholder="Google商品ID"
                    style="width: 200px"
                  />
                </template>
                <template v-else-if="column.key === 'rewardGroup'">
                  <div class="reward-group-cell">
                    <Space wrap>
                      <Button size="small" @click="openRewardPicker(index)">
                        {{ record.rewardGroupId ? '更换奖励组' : '选择奖励组' }}
                      </Button>
                      <Button
                        v-if="record.rewardGroupId"
                        danger
                        size="small"
                        type="link"
                        @click="clearRewardGroup(record)"
                      >
                        清空
                      </Button>
                    </Space>
                    <div v-if="record.rewardGroupId" class="reward-group-name">
                      {{ record.rewardGroupName || '-' }} (ID: {{ record.rewardGroupId }})
                    </div>
                    <div v-else class="sub-text">未选择奖励组</div>
                    <RewardRow v-if="record.rewardItems?.length" :list="record.rewardItems" />
                  </div>
                </template>
                <template v-else-if="column.key === 'actions'">
                  <Button danger type="link" @click="confirmRemoveLevel(index)">删除</Button>
                </template>
              </template>
            </Table>

            <div class="actions">
              <Button @click="addLevel">新增档位</Button>
              <Button :loading="saving" type="primary" @click="submitForm">保存配置</Button>
            </div>
          </TabPane>

          <TabPane key="records" tab="发奖记录">
            <div class="toolbar">
              <Input
                v-model:value="recordQuery.userId"
                allow-clear
                placeholder="用户长ID"
                style="width: 180px"
              />
              <Select
                v-model:value="recordQuery.status"
                :options="statusOptions"
                style="width: 140px"
              />
              <Button :loading="recordLoading" type="primary" @click="searchGrantRecords">
                查询
              </Button>
            </div>
            <Table
              :columns="recordColumns"
              :data-source="recordPage.records"
              :loading="recordLoading"
              :pagination="{
                current: recordPage.current,
                pageSize: recordPage.size,
                showSizeChanger: true,
                total: recordPage.total,
              }"
              row-key="id"
              :scroll="{ x: 1810 }"
              @change="handleGrantTableChange"
            >
              <template #bodyCell="{ column, record }">
                <template v-if="column.key === 'user'">
                  <div class="user-cell">
                    <div
                      v-if="record.userAvatar"
                      class="user-avatar"
                      :style="avatarBackgroundStyle(record.userAvatar)"
                    ></div>
                    <div class="user-main">
                      <div class="user-name">{{ record.userNickname || '-' }}</div>
                      <div class="sub-text">
                        {{ record.account || record.userId || '-' }}
                        <span v-if="record.countryCode"> · {{ record.countryCode }}</span>
                      </div>
                    </div>
                  </div>
                </template>
                <template v-else-if="column.key === 'payPlatform'">
                  <div>{{ record.payPlatform || '-' }}</div>
                  <div class="sub-text">{{ record.paymentMethod || '-' }}</div>
                </template>
                <template v-else-if="column.key === 'rewardGroup'">
                  <div class="reward-group-name">
                    {{ record.rewardGroupName || '-' }} (ID: {{ record.rewardGroupId || '-' }})
                  </div>
                  <RewardRow v-if="record.rewardItems?.length" :list="record.rewardItems" />
                </template>
                <template v-else-if="column.key === 'status'">
                  <Tag :color="grantStatusMeta(record.status).color">
                    {{ grantStatusMeta(record.status).text }}
                  </Tag>
                </template>
                <template v-else-if="column.key === 'sentAt'">
                  {{ record.sentAt || '-' }}
                </template>
                <template v-else-if="column.key === 'lastError'">
                  <span class="error-text">{{ record.lastError || '-' }}</span>
                </template>
              </template>
            </Table>
          </TabPane>
        </Tabs>
      </Card>

      <ActivityResourceGroupSelectDrawer
        :open="groupPickerOpen"
        :sys-origin="selectedSysOrigin"
        @close="groupPickerOpen = false"
        @select="handleRewardGroupSelect"
      />
    </Spin>
  </Page>
</template>

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

.config-row {
  margin-bottom: 16px;
}

.field-label {
  color: rgb(71 85 105);
  font-size: 13px;
}

.sub-text {
  color: rgb(100 116 139);
  font-size: 12px;
}

.reward-group-cell {
  min-width: 0;
}

.reward-group-name {
  color: rgb(15 23 42);
  font-size: 13px;
  margin-top: 8px;
}

.user-cell {
  align-items: center;
  display: flex;
  gap: 10px;
  min-width: 0;
}

.user-avatar {
  background-color: rgb(226 232 240);
  background-position: center;
  background-size: cover;
  border-radius: 50%;
  flex: 0 0 auto;
  height: 36px;
  width: 36px;
}

.user-main {
  min-width: 0;
}

.user-name {
  color: rgb(15 23 42);
  font-size: 13px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.error-text {
  color: rgb(185 28 28);
}

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