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

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

import {
  getRoomTurnoverRewardCurrentRank,
  getRoomTurnoverRewardConfig,
  pageRoomTurnoverRewardRecords,
  saveRoomTurnoverRewardConfig,
} from '#/api/legacy/resident-activity';
import RoomDetailsDrawer from '#/views/app-system/components/room-details-drawer.vue';
import { getAllowedSysOrigins } from '#/views/system/shared';

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

defineOptions({ name: 'ResidentRoomTurnoverRewardPage' });

function createLevel(level = 1, threshold = 100_000, rewardGold = 2_000) {
  return {
    enabled: true,
    id: null,
    level,
    rewardGold,
    turnoverThreshold: threshold,
  };
}

function defaultLevels() {
  return [
    createLevel(1, 100_000, 2_000),
    createLevel(2, 500_000, 15_000),
    createLevel(3, 2_000_000, 80_000),
    createLevel(4, 5_000_000, 250_000),
  ];
}

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 recordLoading = ref(false);
const recordTotal = ref(0);
const recordList = ref<Array<Record<string, any>>>([]);
const rankLoading = ref(false);
const rankList = ref<Array<Record<string, any>>>([]);
const rankMeta = reactive({
  cycleKey: '',
  dateNumber: '',
  periodEndAt: '',
  periodStartAt: '',
  timezone: 'Asia/Riyadh',
});
const roomDetailsOpen = ref(false);
const activeRoomId = ref<number | string>('');

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

const recordQuery = reactive({
  cursor: 1,
  cycleKey: '',
  limit: 20,
  status: '',
});

const rankQuery = reactive({
  limit: 20,
});

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

const levelColumns = [
  { dataIndex: 'enabled', key: 'enabled', title: '启用', width: 90 },
  { dataIndex: 'level', key: 'level', title: '等级', width: 110 },
  { dataIndex: 'turnoverThreshold', key: 'turnoverThreshold', title: '达到流水', width: 220 },
  { dataIndex: 'rewardGold', key: 'rewardGold', title: '奖励房主金币', width: 220 },
  { dataIndex: 'actions', key: 'actions', title: '操作', width: 100 },
];

const recordColumns = [
  { dataIndex: 'cycleKey', key: 'cycleKey', title: '周期', width: 130 },
  { dataIndex: 'room', key: 'room', title: '房间', width: 280 },
  { dataIndex: 'ownerUserId', key: 'ownerUserId', title: '房主ID', width: 150 },
  { dataIndex: 'turnoverAmount', key: 'turnoverAmount', title: '流水', width: 140 },
  { dataIndex: 'level', key: 'level', title: '等级', width: 100 },
  { dataIndex: 'rewardGold', key: 'rewardGold', title: '奖励金币', width: 140 },
  { dataIndex: 'status', key: 'status', title: '状态', width: 110 },
  { dataIndex: 'retryCount', key: 'retryCount', title: '重试次数', width: 110 },
  { dataIndex: 'sentAt', key: 'sentAt', title: '发放时间', width: 180 },
  { dataIndex: 'lastError', key: 'lastError', title: '失败原因', width: 260 },
];

const rankColumns = [
  { dataIndex: 'rank', key: 'rank', title: '排名', width: 90 },
  { dataIndex: 'room', key: 'room', title: '房间', width: 280 },
  { dataIndex: 'ownerUserId', key: 'ownerUserId', title: '房主ID', width: 150 },
  { dataIndex: 'countryName', key: 'countryName', title: '国家', width: 120 },
  { dataIndex: 'turnoverAmount', key: 'turnoverAmount', title: '当前流水', width: 150 },
  { dataIndex: 'matchedLevel', key: 'matchedLevel', title: '命中等级', width: 120 },
  { dataIndex: 'turnoverThreshold', key: 'turnoverThreshold', title: '命中门槛', width: 150 },
  { dataIndex: 'expectedRewardGold', key: 'expectedRewardGold', title: '预计奖励金币', width: 150 },
];

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

function normalizeConfig(result: Record<string, any> | null | undefined) {
  const value = result || {};
  form.configured = Boolean(value.configured);
  form.enabled = Boolean(value.enabled);
  form.id = value.id || 0;
  form.sysOrigin = String(value.sysOrigin || selectedSysOrigin.value || '');
  form.timezone = String(value.timezone || 'Asia/Riyadh');
  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>) => ({
      enabled: item.enabled !== false,
      id: item.id ?? null,
      level: Number(item.level || 0),
      rewardGold: Number(item.rewardGold || 0),
      turnoverThreshold: Number(item.turnoverThreshold || 0),
    }))
    .sort((left: Record<string, any>, right: Record<string, any>) =>
      Number(left.turnoverThreshold || 0) - Number(right.turnoverThreshold || 0),
    );
}

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

async function loadRecords(reset = false) {
  if (!selectedSysOrigin.value) {
    recordList.value = [];
    recordTotal.value = 0;
    return;
  }
  if (reset) {
    recordQuery.cursor = 1;
  }
  recordLoading.value = true;
  try {
    const result = await pageRoomTurnoverRewardRecords({
      ...recordQuery,
      sysOrigin: selectedSysOrigin.value,
    });
    recordList.value = Array.isArray(result.records) ? result.records : [];
    recordTotal.value = Number(result.total || 0);
  } finally {
    recordLoading.value = false;
  }
}

async function loadCurrentRank() {
  if (!selectedSysOrigin.value) {
    rankList.value = [];
    Object.assign(rankMeta, {
      cycleKey: '',
      dateNumber: '',
      periodEndAt: '',
      periodStartAt: '',
      timezone: 'Asia/Riyadh',
    });
    return;
  }
  rankLoading.value = true;
  try {
    const result = await getRoomTurnoverRewardCurrentRank({
      limit: rankQuery.limit,
      sysOrigin: selectedSysOrigin.value,
    });
    rankList.value = Array.isArray(result.records) ? result.records : [];
    rankMeta.cycleKey = String(result.cycleKey || '');
    rankMeta.dateNumber = String(result.dateNumber || '');
    rankMeta.periodEndAt = String(result.periodEndAt || '');
    rankMeta.periodStartAt = String(result.periodStartAt || '');
    rankMeta.timezone = String(result.timezone || 'Asia/Riyadh');
  } finally {
    rankLoading.value = false;
  }
}

async function reloadAll() {
  await Promise.all([loadConfig(), loadCurrentRank(), loadRecords(true)]);
}

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

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

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 seenThresholds = new Set<string>();
  for (const item of levels) {
    const level = Number(item.level || 0);
    const threshold = Number(item.turnoverThreshold || 0);
    const rewardGold = Number(item.rewardGold || 0);
    if (level <= 0 || threshold <= 0 || rewardGold <= 0) {
      message.warning('等级、流水门槛和奖励金币都必须大于 0');
      return false;
    }
    if (seenLevels.has(String(level))) {
      message.warning('奖励等级不能重复');
      return false;
    }
    if (seenThresholds.has(String(threshold))) {
      message.warning('流水门槛不能重复');
      return false;
    }
    seenLevels.add(String(level));
    seenThresholds.add(String(threshold));
  }
  if (form.enabled && enabledLevelCount.value === 0) {
    message.warning('启用配置时至少要启用一个奖励等级');
    return false;
  }
  return true;
}

async function submitForm() {
  if (!validateBeforeSave()) {
    return;
  }
  saving.value = true;
  try {
    await saveRoomTurnoverRewardConfig({
      enabled: Boolean(form.enabled),
      id: form.id || 0,
      levelConfigs: (form.levelConfigs || []).map((item: Record<string, any>) => ({
        enabled: item.enabled !== false,
        id: item.id || 0,
        level: Number(item.level || 0),
        rewardGold: Number(item.rewardGold || 0),
        turnoverThreshold: Number(item.turnoverThreshold || 0),
      })),
      sysOrigin: selectedSysOrigin.value,
      timezone: String(form.timezone || '').trim(),
    });
    message.success('保存成功');
    await reloadAll();
  } finally {
    saving.value = false;
  }
}

function statusColor(status: string) {
  switch (status) {
    case 'SUCCESS':
      return 'success';
    case 'FAILED':
      return 'error';
    case 'PENDING':
      return 'processing';
    default:
      return 'default';
  }
}

function formatNumber(value: number | string | undefined) {
  const numeric = Number(value || 0);
  return Number.isFinite(numeric) ? numeric.toLocaleString() : '0';
}

function coverBackgroundStyle(url?: string) {
  const coverUrl = String(url || '').trim();
  return coverUrl ? { backgroundImage: `url(${JSON.stringify(coverUrl)})` } : {};
}

function handleRecordPageChange(page: number, pageSize: number) {
  recordQuery.cursor = page;
  recordQuery.limit = pageSize;
  void loadRecords();
}

function handleRankLimitChange() {
  void loadCurrentRank();
}

function openRoomDetails(roomId?: number | string) {
  if (!roomId) {
    return;
  }
  activeRoomId.value = roomId;
  roomDetailsOpen.value = true;
}

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

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

watch(
  selectedSysOrigin,
  (value) => {
    if (value) {
      void reloadAll();
    }
  },
  { 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="form.enabled ? 'success' : 'default'">
          {{ form.enabled ? '已启用' : '已关闭' }}
        </Tag>
        <Tag color="processing">按达到的最高档发放一次</Tag>
        <Button :loading="loading" @click="reloadAll">刷新</Button>
      </div>

      <div class="config-row">
        <Space align="center" wrap>
          <span class="field-label">启用</span>
          <Switch v-model:checked="form.enabled" />
          <span class="field-label">结算时区</span>
          <Input v-model:value="form.timezone" style="width: 180px" />
          <span class="sub-text">更新时间：{{ form.updateTime || '-' }}</span>
        </Space>
      </div>

      <Table
        :columns="levelColumns"
        :data-source="form.levelConfigs"
        :loading="loading"
        :pagination="false"
        row-key="level"
        :scroll="{ x: 760 }"
      >
        <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 === 'turnoverThreshold'">
            <InputNumber
              v-model:value="record.turnoverThreshold"
              :min="1"
              :precision="0"
              style="width: 180px"
            />
          </template>
          <template v-else-if="column.key === 'rewardGold'">
            <InputNumber
              v-model:value="record.rewardGold"
              :min="1"
              :precision="0"
              style="width: 180px"
            />
          </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>
    </Card>

    <Card :bordered="false" class="record-card" title="当前房间排行榜">
      <div class="toolbar">
        <Tag color="processing">{{ rankMeta.cycleKey || '-' }}</Tag>
        <Tag>{{ rankMeta.timezone || '-' }}</Tag>
        <span class="sub-text">
          {{ rankMeta.periodStartAt || '-' }} - {{ rankMeta.periodEndAt || '-' }}
        </span>
        <span class="sub-text">统计周：{{ rankMeta.dateNumber || '-' }}</span>
        <Select
          v-model:value="rankQuery.limit"
          :options="[
            { label: 'Top 20', value: 20 },
            { label: 'Top 50', value: 50 },
            { label: 'Top 100', value: 100 },
          ]"
          style="width: 120px"
          @change="handleRankLimitChange"
        />
        <Button :loading="rankLoading" type="primary" @click="loadCurrentRank">刷新排行</Button>
      </div>

      <Table
        :columns="rankColumns"
        :data-source="rankList"
        :loading="rankLoading"
        :pagination="false"
        row-key="roomId"
        :scroll="{ x: 1410 }"
      >
        <template #bodyCell="{ column, record }">
          <template v-if="column.key === 'room'">
            <div class="room-cell">
              <div
                v-if="record.roomCover"
                class="room-cover"
                :style="coverBackgroundStyle(record.roomCover)"
              />
              <div v-else class="room-cover placeholder">R</div>
              <div class="room-copy">
                <Button type="link" @click="openRoomDetails(record.roomId)">
                  {{ record.roomName || '-' }}
                </Button>
                <div class="sub-text">{{ record.roomAccount || record.roomId || '-' }}</div>
              </div>
            </div>
          </template>
          <template v-else-if="column.key === 'turnoverAmount'">
            {{ formatNumber(record.turnoverAmount) }}
          </template>
          <template v-else-if="column.key === 'matchedLevel'">
            <Tag v-if="record.matchedLevel" color="success">Lv {{ record.matchedLevel }}</Tag>
            <Tag v-else>未命中</Tag>
          </template>
          <template v-else-if="column.key === 'turnoverThreshold'">
            {{ record.turnoverThreshold ? formatNumber(record.turnoverThreshold) : '-' }}
          </template>
          <template v-else-if="column.key === 'expectedRewardGold'">
            {{ record.expectedRewardGold ? formatNumber(record.expectedRewardGold) : '-' }}
          </template>
        </template>
      </Table>
    </Card>

    <Card :bordered="false" class="record-card" title="发奖记录">
      <div class="toolbar">
        <Input
          v-model:value="recordQuery.cycleKey"
          allow-clear
          placeholder="周期 key"
          style="width: 180px"
          @press-enter="loadRecords(true)"
        />
        <Select
          v-model:value="recordQuery.status"
          :options="statusOptions"
          style="width: 140px"
          @change="loadRecords(true)"
        />
        <Button :loading="recordLoading" type="primary" @click="loadRecords(true)">查询</Button>
      </div>

      <Table
        :columns="recordColumns"
        :data-source="recordList"
        :loading="recordLoading"
        :pagination="false"
        row-key="id"
        :scroll="{ x: 1560 }"
      >
        <template #bodyCell="{ column, record }">
          <template v-if="column.key === 'room'">
            <div class="room-cell">
              <div
                v-if="record.roomCover"
                class="room-cover"
                :style="coverBackgroundStyle(record.roomCover)"
              />
              <div v-else class="room-cover placeholder">R</div>
              <div class="room-copy">
                <Button type="link" @click="openRoomDetails(record.roomId)">
                  {{ record.roomName || '-' }}
                </Button>
                <div class="sub-text">{{ record.roomAccount || record.roomId || '-' }}</div>
              </div>
            </div>
          </template>
          <template v-else-if="column.key === 'turnoverAmount'">
            {{ formatNumber(record.turnoverAmount) }}
          </template>
          <template v-else-if="column.key === 'rewardGold'">
            {{ formatNumber(record.rewardGold) }}
          </template>
          <template v-else-if="column.key === 'status'">
            <Tag :color="statusColor(record.status)">{{ record.status || '-' }}</Tag>
          </template>
        </template>
      </Table>

      <div v-if="recordTotal > 0" class="pager">
        <Pagination
          :current="recordQuery.cursor"
          :page-size="recordQuery.limit"
          :total="recordTotal"
          show-size-changer
          @change="handleRecordPageChange"
          @showSizeChange="handleRecordPageChange"
        />
      </div>
    </Card>

    <RoomDetailsDrawer
      :open="roomDetailsOpen"
      :room-id="activeRoomId"
      @close="roomDetailsOpen = false"
    />
  </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;
}

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

.record-card {
  margin-top: 16px;
}

.room-cell {
  align-items: center;
  display: flex;
  gap: 12px;
}

.room-cover {
  background-position: center;
  background-repeat: no-repeat;
  background-size: cover;
  border-radius: 8px;
  flex: 0 0 40px;
  height: 40px;
  width: 40px;
}

.room-cover.placeholder {
  align-items: center;
  background: rgb(226 232 240);
  color: rgb(100 116 139);
  display: flex;
  font-size: 13px;
  font-weight: 600;
  justify-content: center;
}

.room-copy {
  min-width: 0;
}

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