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

import { Page } from '@vben/common-ui';
import {
  RotateCw,
  Search as SearchIcon,
} from '@vben/icons';
import { useAccessStore } from '@vben/stores';

import {
  Button,
  Card,
  Checkbox,
  DatePicker,
  Image,
  Input,
  InputNumber,
  message,
  Modal,
  Pagination,
  Popover,
  Select,
  Space,
  Switch,
  Table,
  TabPane,
  Tabs,
  Tag,
  Tooltip,
} from 'antdv-next';

import {
  addAllGiftRegion,
  getPairCpGiveGiftId,
  giftTable,
  listGiftBySysOrigin,
  pushPairCpGiveGiftId,
  switchDelStatus,
  updateGift,
  updateGiftSort,
} from '#/api/legacy/gift';
import { getAccessImgUrl } from '#/api/legacy/oss';
import {
  addWeekStarGroup,
  delWeekStarGroup,
  getWeekStarGroupPage,
  regionConfigTable,
} from '#/api/legacy/system';
import AdminConfigTable from '#/views/_shared/admin-config-table.vue';
import { formatDate, getAllowedSysOrigins } from '#/views/system/shared';

import GiftBatchDrawer from './components/gift-batch-drawer.vue';
import GiftFormModal from './components/gift-form-modal.vue';
import {
  CP_RELATION_TYPE_OPTIONS,
  GIFT_CONFIG_TAB_OPTIONS,
  GIFT_SPECIAL_OPTIONS,
} from './constants';

defineOptions({ name: 'OperateGiftConfig' });

const SHELF_OPTIONS = [
  { label: '下架', value: true },
  { label: '上架', value: false },
];

const GIFT_CHARGE_TYPE_OPTIONS = [
  { label: '金币', value: 'GOLD' },
  { label: '钻石', value: 'DIAMOND' },
  { disabled: true, label: '免费', value: 'FREE' },
];

const GIFT_TAB_LABEL_MAP = new Map(
  GIFT_CONFIG_TAB_OPTIONS.map((item) => [String(item.value), item.name]),
);
const CP_RELATION_TYPE_LABEL_MAP = new Map(
  CP_RELATION_TYPE_OPTIONS.map((item) => [String(item.value), item.name]),
);

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

const activeTab = ref('setting');

const settingLoading = ref(false);
const settingList = ref<Array<Record<string, any>>>([]);
const settingTotal = ref(0);
const regions = ref<Array<Record<string, any>>>([]);
const settingRangeDate = ref<[string, string] | null>(null);
const editingGiftSortId = ref('');
const editingGiftSortValue = ref('');
const savingGiftSortId = ref('');
const giftSortInputRefs = new Map<string, any>();
const settingFilterOpen = reactive<Record<string, boolean>>({});
const settingQuery = reactive({
  cursor: 1,
  del: false as boolean | undefined,
  endCreateDate: '',
  giftId: '',
  giftName: '',
  giftTab: '',
  limit: 20,
  region: '',
  sortType: 'CREATE_TIME_DESC',
  startCreateDate: '',
  sysOrigin: '',
  type: '',
  userId: '',
});

const giftFormOpen = ref(false);
const giftBatchOpen = ref(false);
const activeGiftRow = ref<null | Record<string, any>>(null);
const selectedGiftRowKeys = ref<Array<number | string>>([]);
const selectedGiftRowMap = ref<Record<string, Record<string, any>>>({});
const batchEditOpen = ref(false);
const batchEditSaving = ref(false);
const batchEditFields = reactive({
  cpRelationType: false,
  del: false,
  giftCandy: false,
  giftIntegral: false,
  giftTab: false,
  specialList: false,
  sort: false,
  type: false,
});
const batchEditForm = reactive({
  cpRelationType: 'CP',
  del: false as boolean,
  giftCandy: null as null | number,
  giftIntegral: null as null | number,
  giftTab: 'ORDINARY',
  specialList: [] as string[],
  sort: null as null | number,
  type: 'GOLD',
});
const addRegionOpen = ref(false);
const addRegionSaving = ref(false);
const addRegionForm = reactive({
  regionId: '',
});

const weekStarLoading = ref(false);
const weekStarList = ref<Array<Record<string, any>>>([]);
const weekStarTotal = ref(0);
const weekStarQuery = reactive({
  cursor: 1,
  limit: 20,
  sysOrigin: '',
});
const weekStarOpen = ref(false);
const weekStarSaving = ref(false);
const weekStarForm = reactive({
  giftOne: '',
  giftThree: '',
  giftTwo: '',
  sysOrigin: '',
});
const weekStarGiftOptions = ref<Array<Record<string, any>>>([]);

function getWeekStarSelectOptions(currentValue: string) {
  return weekStarGiftOptions.value.map((item) => ({
    disabled:
      isWeekStarGiftDisabled(item.id) &&
      String(currentValue || '') !== String(item.id || ''),
    label: String(item.giftName || item.id || '-'),
    value: item.id as any,
  }));
}

const cpLoading = ref(false);
const cpSaving = ref(false);
const cpForm = reactive({
  giftId: '',
  sysOrigin: '',
});

const settingColumns = [
  { dataIndex: 'giftCode', key: 'giftCode', title: 'Code', width: 160 },
  { dataIndex: 'giftPhoto', key: 'giftPhoto', title: '封面', width: 100 },
  { dataIndex: 'giftName', key: 'giftName', title: '名称', width: 160 },
  { dataIndex: 'giftCandy', key: 'giftCandy', title: '金币', width: 100 },
  { dataIndex: 'giftIntegral', key: 'giftIntegral', title: '积分', width: 100 },
  { dataIndex: 'regionNameStr', key: 'regionNameStr', title: '区域', width: 180 },
  { dataIndex: 'giftTab', key: 'giftTab', title: '礼物类型', width: 120 },
  { dataIndex: 'cpRelationType', key: 'cpRelationType', title: 'CP礼物类型', width: 120 },
  { dataIndex: 'typeName', key: 'typeName', title: '收费类型', width: 120 },
  { dataIndex: 'sort', key: 'sort', title: '排序权重', width: 100 },
  { align: 'center' as const, className: 'switch-column', dataIndex: 'del', fixed: 'right' as const, key: 'del', title: '上/下架', width: 84 },
  { dataIndex: 'createTime', key: 'createTime', title: '创建时间', width: 180 },
  { dataIndex: 'userBaseInfo', key: 'userBaseInfo', title: '专属礼物归属人', width: 180 },
  { align: 'center' as const, className: 'action-column', dataIndex: 'actions', fixed: 'right' as const, key: 'actions', title: '操作', width: 84 },
];

const settingFilterableColumnKeys = new Set([
  'createTime',
  'del',
  'giftCandy',
  'giftName',
  'giftTab',
  'regionNameStr',
  'sort',
  'typeName',
]);

const regionOptions = computed(() =>
  regions.value.map((item) => ({
    label: String(item.regionName || item.name || item.id || '-'),
    value: item.id as any,
  })),
);
const giftTabOptions = GIFT_CONFIG_TAB_OPTIONS.map((item) => ({
  label: item.name,
  value: item.value as any,
}));
const giftChargeTypeOptions = GIFT_CHARGE_TYPE_OPTIONS.map((item) => ({
  label: item.label,
  value: item.value as any,
}));
const giftSpecialOptions = GIFT_SPECIAL_OPTIONS.map((item) => ({
  label: item.name,
  value: item.value as any,
}));

const settingPageCount = computed(() =>
  Math.max(1, Math.ceil(settingTotal.value / settingQuery.limit)),
);
const settingHasMore = computed(() => settingList.value.length < settingTotal.value);
const settingSummaryText = computed(
  () =>
    `共 ${settingTotal.value} 条 / ${settingPageCount.value} 页，已加载 ${settingList.value.length} 条`,
);
const selectedGiftCount = computed(() => selectedGiftRowKeys.value.length);
const selectedGiftRows = computed(() =>
  selectedGiftRowKeys.value
    .map((key) => selectedGiftRowMap.value[String(key)])
    .filter(Boolean),
);
const settingRowSelection = computed(() => ({
  preserveSelectedRowKeys: true,
  selectedRowKeys: selectedGiftRowKeys.value,
  onChange: (keys: Array<number | string>, rows: Array<Record<string, any>>) => {
    const previousMap = selectedGiftRowMap.value;
    const nextMap: Record<string, Record<string, any>> = {};
    keys.forEach((key) => {
      const stringKey = String(key);
      if (previousMap[stringKey]) {
        nextMap[stringKey] = previousMap[stringKey];
      }
    });
    rows.forEach((row) => {
      const stringKey = String(row.id || '');
      if (stringKey) {
        nextMap[stringKey] = row;
      }
    });
    selectedGiftRowKeys.value = keys;
    selectedGiftRowMap.value = nextMap;
  },
}));

const weekStarColumns = [
  { dataIndex: 'id', key: 'id', title: '编号', width: 120 },
  { dataIndex: 'sysOrigin', key: 'sysOrigin', title: '归属系统', width: 120 },
  { dataIndex: 'displayNumber', key: 'displayNumber', title: '展示次数', width: 120 },
  { dataIndex: 'sysGiftConfigs', key: 'sysGiftConfigs', title: '礼物信息', width: 360 },
  { dataIndex: 'type', key: 'type', title: '状态', width: 120 },
  { dataIndex: 'actions', key: 'actions', title: '操作', width: 100 },
];

watch(settingRangeDate, (value) => {
  settingQuery.startCreateDate = value?.[0] || '';
  settingQuery.endCreateDate = value?.[1] || '';
});

watch(
  sysOriginOptions,
  (options) => {
    const first = String(options[0]?.value || '');
    if (!settingQuery.sysOrigin && first) {
      settingQuery.sysOrigin = first;
      cpForm.sysOrigin = first;
      weekStarQuery.sysOrigin = first;
      void loadSetting(true);
      void loadRegions(first);
      void loadCp();
      void loadWeekStar(true);
    }
  },
  { immediate: true },
);

async function loadRegions(sysOrigin: string) {
  if (!sysOrigin) {
    regions.value = [];
    return;
  }
  regions.value = (await regionConfigTable({ sysOrigin })) || [];
}

function clearGiftSelection() {
  selectedGiftRowKeys.value = [];
  selectedGiftRowMap.value = {};
}

async function loadSetting(reset = false, append = false) {
  if (!settingQuery.sysOrigin) {
    return;
  }
  if (reset) {
    settingQuery.cursor = 1;
    clearGiftSelection();
  }
  settingLoading.value = true;
  try {
    const result = await giftTable({ ...settingQuery });
    const records = result.records || [];
    if (append) {
      const recordMap = new Map<string, Record<string, any>>();
      settingList.value.forEach((item) => {
        recordMap.set(String(item.id || ''), item);
      });
      records.forEach((item: Record<string, any>) => {
        recordMap.set(String(item.id || ''), item);
      });
      settingList.value = [...recordMap.values()];
    } else {
      settingList.value = records;
    }
    settingTotal.value = result.total || 0;
  } finally {
    settingLoading.value = false;
  }
}

async function loadWeekStar(reset = false) {
  if (!weekStarQuery.sysOrigin) {
    return;
  }
  if (reset) {
    weekStarQuery.cursor = 1;
  }
  weekStarLoading.value = true;
  try {
    const result = await getWeekStarGroupPage({ ...weekStarQuery });
    weekStarList.value = result.records || [];
    weekStarTotal.value = result.total || 0;
  } finally {
    weekStarLoading.value = false;
  }
}

async function loadCp() {
  if (!cpForm.sysOrigin) {
    return;
  }
  cpLoading.value = true;
  try {
    cpForm.giftId = String((await getPairCpGiveGiftId(cpForm.sysOrigin)) || '');
  } finally {
    cpLoading.value = false;
  }
}

async function loadNextSettingPage() {
  if (settingLoading.value || !settingHasMore.value) {
    return;
  }
  const nextPage = settingQuery.cursor + 1;
  if (nextPage > settingPageCount.value) {
    return;
  }
  settingQuery.cursor = nextPage;
  await loadSetting(false, true);
}

function handleWeekStarPageChange(page: number, pageSize: number) {
  weekStarQuery.cursor = page;
  weekStarQuery.limit = pageSize;
  void loadWeekStar();
}

async function handleSwitch(record: Record<string, any>) {
  await switchDelStatus(record.id, record.del);
  message.success('操作成功');
  await loadSetting(true);
}

function setGiftSortInputRef(id: number | string, element: any) {
  const key = String(id || '');
  if (!key) {
    return;
  }
  if (element) {
    giftSortInputRefs.set(key, element);
  } else {
    giftSortInputRefs.delete(key);
  }
}

function focusGiftSortInput(id: number | string) {
  void nextTick(() => {
    const element = giftSortInputRefs.get(String(id || ''));
    if (typeof element?.focus === 'function') {
      element.focus();
      return;
    }
    element?.$el?.querySelector?.('input')?.focus?.();
  });
}

function startGiftSortEdit(record: Record<string, any>) {
  const id = String(record.id || '');
  if (!id || savingGiftSortId.value === id) {
    return;
  }
  editingGiftSortId.value = id;
  editingGiftSortValue.value = String(record.sort ?? '');
  focusGiftSortInput(id);
}

function cancelGiftSortEdit() {
  editingGiftSortId.value = '';
  editingGiftSortValue.value = '';
}

async function saveGiftSort(record: Record<string, any>) {
  const id = String(record.id || '');
  if (!id || editingGiftSortId.value !== id || savingGiftSortId.value === id) {
    return;
  }
  const nextSort = Number(editingGiftSortValue.value);
  if (!Number.isInteger(nextSort)) {
    message.warning('权重必须是整数');
    focusGiftSortInput(id);
    return;
  }
  const oldSort = Number(record.sort ?? 0);
  if (nextSort === oldSort) {
    cancelGiftSortEdit();
    return;
  }
  savingGiftSortId.value = id;
  try {
    await updateGiftSort({
      id: record.id,
      sort: nextSort,
    });
    record.sort = nextSort;
    message.success('权重已保存');
    cancelGiftSortEdit();
  } finally {
    savingGiftSortId.value = '';
  }
}

function stringifyCellValue(value: any) {
  if (value === undefined || value === null || value === '') {
    return '-';
  }
  return String(value);
}

function getColumnValue(record: Record<string, any>, column: Record<string, any>) {
  const dataIndex = column?.dataIndex;
  if (Array.isArray(dataIndex)) {
    let value = record;
    for (const key of dataIndex) {
      value = value?.[String(key)];
    }
    return value;
  }
  if (dataIndex === undefined || dataIndex === null) {
    return undefined;
  }
  return record?.[String(dataIndex)];
}

function isSettingFilterableColumn(key: unknown) {
  return settingFilterableColumnKeys.has(String(key));
}

function setSettingFilterOpen(key: unknown, open: boolean) {
  settingFilterOpen[String(key)] = open;
}

function hasSettingColumnFilter(key: unknown) {
  switch (String(key)) {
    case 'createTime': {
      return Boolean(settingQuery.startCreateDate || settingQuery.endCreateDate);
    }
    case 'del': {
      return settingQuery.del !== undefined;
    }
    case 'giftCandy': {
      return settingQuery.sortType === 'AMOUNT_DESC';
    }
    case 'giftName': {
      return settingQuery.giftName.trim() !== '';
    }
    case 'giftTab': {
      return Boolean(settingQuery.giftTab);
    }
    case 'regionNameStr': {
      return Boolean(settingQuery.region);
    }
    case 'sort': {
      return settingQuery.sortType === 'SORT_DESC';
    }
    case 'typeName': {
      return Boolean(settingQuery.type);
    }
    default: {
      return false;
    }
  }
}

function resetSettingColumnFilter(key: unknown) {
  switch (String(key)) {
    case 'createTime': {
      settingRangeDate.value = null;
      settingQuery.startCreateDate = '';
      settingQuery.endCreateDate = '';
      break;
    }
    case 'del': {
      settingQuery.del = undefined;
      break;
    }
    case 'giftCandy': {
      settingQuery.sortType = 'CREATE_TIME_DESC';
      break;
    }
    case 'giftName': {
      settingQuery.giftName = '';
      break;
    }
    case 'giftTab': {
      settingQuery.giftTab = '';
      break;
    }
    case 'regionNameStr': {
      settingQuery.region = '';
      break;
    }
    case 'sort': {
      settingQuery.sortType = 'CREATE_TIME_DESC';
      break;
    }
    case 'typeName': {
      settingQuery.type = '';
      break;
    }
  }
}

function applySettingColumnFilter(key: unknown) {
  settingFilterOpen[String(key)] = false;
  void loadSetting(true);
}

function clearSettingColumnFilter(key: unknown) {
  resetSettingColumnFilter(key);
  applySettingColumnFilter(key);
}

function resetAllSettingColumnFilters() {
  settingQuery.del = undefined;
  settingQuery.endCreateDate = '';
  settingQuery.giftId = '';
  settingQuery.giftName = '';
  settingQuery.giftTab = '';
  settingQuery.region = '';
  settingQuery.sortType = 'CREATE_TIME_DESC';
  settingQuery.startCreateDate = '';
  settingQuery.type = '';
  settingQuery.userId = '';
  settingRangeDate.value = null;
  void loadSetting(true);
}

function applySettingSort(sortType: string, key: unknown) {
  settingQuery.sortType = sortType;
  applySettingColumnFilter(key);
}

function getGiftTabName(value: any) {
  const stringValue = String(value || '');
  return GIFT_TAB_LABEL_MAP.get(stringValue) || stringifyCellValue(value);
}

function getCpRelationTypeName(value: any) {
  const stringValue = String(value || '');
  return CP_RELATION_TYPE_LABEL_MAP.get(stringValue) || stringifyCellValue(value);
}

function normalizeMultiValue(value: any) {
  if (Array.isArray(value)) {
    return value.filter((item) => item !== '' && item !== null && item !== undefined);
  }
  if (value === '' || value === null || value === undefined) {
    return [];
  }
  return String(value)
    .split(',')
    .map((item) => item.trim())
    .filter(Boolean);
}

function resetBatchEditForm() {
  Object.assign(batchEditFields, {
    cpRelationType: false,
    del: false,
    giftCandy: false,
    giftIntegral: false,
    giftTab: false,
    specialList: false,
    sort: false,
    type: false,
  });
  Object.assign(batchEditForm, {
    cpRelationType: 'CP',
    del: false,
    giftCandy: null,
    giftIntegral: null,
    giftTab: 'ORDINARY',
    specialList: [],
    sort: null,
    type: 'GOLD',
  });
}

function openBatchEditModal() {
  if (selectedGiftCount.value <= 0) {
    message.warning('请先选择礼物');
    return;
  }
  resetBatchEditForm();
  batchEditOpen.value = true;
}

function hasBatchEditField() {
  return Object.values(batchEditFields).some(Boolean);
}

function validateBatchEditForm() {
  if (!hasBatchEditField()) {
    message.warning('请选择要修改的字段');
    return false;
  }
  if (batchEditFields.giftTab && !batchEditForm.giftTab) {
    message.warning('请选择礼物类型');
    return false;
  }
  if (batchEditFields.cpRelationType && !batchEditForm.cpRelationType) {
    message.warning('请选择CP礼物类型');
    return false;
  }
  if (batchEditFields.type && !batchEditForm.type) {
    message.warning('请选择收费类型');
    return false;
  }
  if (batchEditFields.specialList && batchEditForm.specialList.length === 0) {
    message.warning('请选择特效');
    return false;
  }
  if (
    batchEditFields.giftCandy &&
    (batchEditForm.giftCandy === null || batchEditForm.giftCandy < 0)
  ) {
    message.warning('请输入正确的金币');
    return false;
  }
  if (
    batchEditFields.giftIntegral &&
    (batchEditForm.giftIntegral === null || batchEditForm.giftIntegral < 0)
  ) {
    message.warning('请输入正确的积分');
    return false;
  }
  if (
    batchEditFields.sort &&
    (batchEditForm.sort === null || !Number.isInteger(Number(batchEditForm.sort)))
  ) {
    message.warning('排序必须是整数');
    return false;
  }
  return true;
}

function buildGiftBatchEditPayload(row: Record<string, any>) {
  const nextType = batchEditFields.type ? batchEditForm.type : row.type;
  const nextGiftTab = batchEditFields.giftTab ? batchEditForm.giftTab : row.giftTab;
  return {
    ...row,
    cpRelationType:
      nextGiftTab === 'CP'
        ? batchEditFields.cpRelationType
          ? batchEditForm.cpRelationType
          : row.cpRelationType || 'CP'
        : '',
    giftCandy:
      nextType === 'FREE'
        ? ''
        : batchEditFields.giftCandy
          ? batchEditForm.giftCandy
          : row.giftCandy,
    giftIntegral:
      nextType === 'FREE'
        ? ''
        : batchEditFields.giftIntegral
          ? batchEditForm.giftIntegral
          : row.giftIntegral,
    giftTab: nextGiftTab,
    regionList: normalizeMultiValue(row.regions || row.regionList),
    sort: batchEditFields.sort ? batchEditForm.sort : row.sort,
    specialList: batchEditFields.specialList
      ? [...batchEditForm.specialList]
      : normalizeMultiValue(row.special || row.specialList),
    type: nextType,
  };
}

async function handleBatchEditSubmit() {
  if (!validateBatchEditForm()) {
    return;
  }
  const rows = selectedGiftRows.value as Array<Record<string, any>>;
  if (rows.length === 0) {
    message.warning('请先选择礼物');
    return;
  }
  const shouldUpdateConfig =
    batchEditFields.giftTab ||
    batchEditFields.cpRelationType ||
    batchEditFields.type ||
    batchEditFields.giftCandy ||
    batchEditFields.giftIntegral ||
    batchEditFields.specialList ||
    batchEditFields.sort;
  batchEditSaving.value = true;
  let successCount = 0;
  let failedCount = 0;
  try {
    for (const row of rows) {
      try {
        if (shouldUpdateConfig) {
          await updateGift(buildGiftBatchEditPayload(row));
        }
        if (
          batchEditFields.del &&
          String(row.del) !== String(batchEditForm.del)
        ) {
          await switchDelStatus(row.id, batchEditForm.del);
        }
        successCount += 1;
      } catch (error) {
        console.error(error);
        failedCount += 1;
      }
    }
    if (failedCount > 0) {
      message.error(`已修改 ${successCount} 个，${failedCount} 个失败`);
      return;
    }
    message.success(`已修改 ${successCount} 个礼物`);
    batchEditOpen.value = false;
    clearGiftSelection();
    await loadSetting(true);
  } finally {
    batchEditSaving.value = false;
  }
}

function openGiftCreate() {
  activeGiftRow.value = null;
  giftFormOpen.value = true;
}

function openGiftEdit(row: Record<string, any>) {
  activeGiftRow.value = row;
  giftFormOpen.value = true;
}

async function openAddRegionModal() {
  if (!settingQuery.sysOrigin) {
    message.warning('请先选择平台');
    return;
  }
  if (regions.value.length <= 0) {
    await loadRegions(settingQuery.sysOrigin);
  }
  addRegionForm.regionId = '';
  addRegionOpen.value = true;
}

async function handleAddRegionSubmit() {
  if (!settingQuery.sysOrigin || !addRegionForm.regionId) {
    message.warning('请选择要追加的区域');
    return;
  }
  addRegionSaving.value = true;
  try {
    await addAllGiftRegion({
      regionId: addRegionForm.regionId,
      sysOrigin: settingQuery.sysOrigin,
    });
    message.success('追加成功');
    addRegionOpen.value = false;
    await loadSetting(true);
  } finally {
    addRegionSaving.value = false;
  }
}

async function openWeekStarModal() {
  weekStarForm.sysOrigin = weekStarQuery.sysOrigin;
  weekStarForm.giftOne = '';
  weekStarForm.giftTwo = '';
  weekStarForm.giftThree = '';
  weekStarGiftOptions.value = await listGiftBySysOrigin(weekStarForm.sysOrigin);
  weekStarOpen.value = true;
}

function isWeekStarGiftDisabled(value: number | string) {
  return (
    String(weekStarForm.giftOne) === String(value) ||
    String(weekStarForm.giftTwo) === String(value) ||
    String(weekStarForm.giftThree) === String(value)
  );
}

async function handleWeekStarSubmit() {
  if (
    !weekStarForm.sysOrigin ||
    !weekStarForm.giftOne ||
    !weekStarForm.giftTwo ||
    !weekStarForm.giftThree
  ) {
    message.warning('请完整选择三组礼物');
    return;
  }
  weekStarSaving.value = true;
  try {
    await addWeekStarGroup({
      giftIds: [weekStarForm.giftOne, weekStarForm.giftTwo, weekStarForm.giftThree],
      sysOrigin: weekStarForm.sysOrigin,
    });
    message.success('保存成功');
    weekStarOpen.value = false;
    await loadWeekStar(true);
  } finally {
    weekStarSaving.value = false;
  }
}

async function handleWeekStarDelete(row: Record<string, any>) {
  await delWeekStarGroup(row.id);
  message.success('删除成功');
  await loadWeekStar(true);
}

async function handleCpSave() {
  if (!cpForm.sysOrigin || !cpForm.giftId) {
    message.warning('请输入礼物ID');
    return;
  }
  cpSaving.value = true;
  try {
    await pushPairCpGiveGiftId(cpForm.giftId, cpForm.sysOrigin);
    message.success('保存成功');
    await loadCp();
  } finally {
    cpSaving.value = false;
  }
}
</script>

<template>
  <Page auto-content-height content-class="gift-page-content" title="礼物管理">
    <Card class="gift-page-card">
      <Tabs v-model:active-key="activeTab">
        <TabPane key="setting" tab="礼物配置" />
        <TabPane key="weekStar" tab="周星礼物配置" />
        <TabPane key="cp" tab="CP组合赠送礼物" />
      </Tabs>

      <div v-if="activeTab === 'setting'" class="gift-setting-panel">
        <Space class="toolbar" wrap>
          <SysOriginSelect
            v-model:value="settingQuery.sysOrigin"
            style="width: 160px"
            @change="loadRegions(settingQuery.sysOrigin); loadSetting(true)"
            :options="sysOriginOptions"
          />
          <Button type="primary" @click="openGiftCreate">
            新增礼物
          </Button>
          <Button type="primary" @click="giftBatchOpen = true">
            批量导入
          </Button>
          <Button :disabled="selectedGiftCount === 0" @click="openBatchEditModal">
            批量修改{{ selectedGiftCount > 0 ? `(${selectedGiftCount})` : '' }}
          </Button>
          <Button danger @click="openAddRegionModal">
            添加全部礼物区域
          </Button>
        </Space>

        <AdminConfigTable
          auto-height
          class="gift-setting-table"
          :columns="settingColumns"
          :data-source="settingList"
          :has-more="settingHasMore"
          infinite
          :loading="settingLoading"
          :current="settingQuery.cursor"
          :page-size="settingQuery.limit"
          plain
          row-key="id"
          :row-selection="settingRowSelection"
          :scroll-x="1680"
          :show-pager="false"
          :summary-text="settingSummaryText"
          :total="settingTotal"
          @load-more="loadNextSettingPage"
        >
          <template #headerCell="{ column }">
            <template v-if="column.key === 'actions'">
              <div class="column-title column-title--actions">
                <span>{{ column.title }}</span>
                <Tooltip title="重置筛选">
                  <Button
                    class="filter-reset-button"
                    size="small"
                    type="text"
                    @click="resetAllSettingColumnFilters"
                  >
                    <RotateCw class="filter-icon-svg" />
                  </Button>
                </Tooltip>
              </div>
            </template>
            <template v-else-if="isSettingFilterableColumn(column.key)">
              <div class="column-title">
                <Popover
                  :open="Boolean(settingFilterOpen[String(column.key)])"
                  overlay-class-name="gift-filter-popover"
                  placement="bottomLeft"
                  trigger="click"
                  @open-change="(open: boolean) => setSettingFilterOpen(column.key, open)"
                >
                  <template #content>
                    <div class="column-filter-panel">
                      <template v-if="column.key === 'giftName'">
                        <Input
                          v-model:value="settingQuery.giftName"
                          allow-clear
                          autofocus
                          placeholder="输入礼物名称"
                          @press-enter="applySettingColumnFilter(column.key)"
                        />
                      </template>
                      <template v-else-if="column.key === 'giftTab'">
                        <Select
                          v-model:value="settingQuery.giftTab"
                          allow-clear
                          :options="giftTabOptions"
                          option-label-prop="label"
                          placeholder="选择礼物类型"
                        />
                      </template>
                      <template v-else-if="column.key === 'typeName'">
                        <Select
                          v-model:value="settingQuery.type"
                          allow-clear
                          :options="giftChargeTypeOptions"
                          option-label-prop="label"
                          placeholder="选择收费类型"
                        />
                      </template>
                      <template v-else-if="column.key === 'del'">
                        <Select
                          v-model:value="settingQuery.del"
                          allow-clear
                          :options="SHELF_OPTIONS.map((item) => ({ label: `${item.label}`, value: item.value as any }))"
                          option-label-prop="label"
                          placeholder="选择上/下架"
                        />
                      </template>
                      <template v-else-if="column.key === 'regionNameStr'">
                        <Select
                          v-model:value="settingQuery.region"
                          allow-clear
                          :options="regionOptions"
                          option-label-prop="label"
                          placeholder="选择区域"
                          show-search
                        />
                      </template>
                      <template v-else-if="column.key === 'createTime'">
                        <DatePicker.RangePicker
                          v-model:value="settingRangeDate"
                          show-time
                          style="width: 100%"
                          value-format="x"
                        />
                        <Button
                          block
                          size="small"
                          @click="applySettingSort('CREATE_TIME_DESC', column.key)"
                        >
                          创建时间降序
                        </Button>
                      </template>
                      <template v-else-if="column.key === 'giftCandy'">
                        <Button
                          block
                          size="small"
                          @click="applySettingSort('AMOUNT_DESC', column.key)"
                        >
                          金额降序
                        </Button>
                      </template>
                      <template v-else-if="column.key === 'sort'">
                        <Button
                          block
                          size="small"
                          @click="applySettingSort('SORT_DESC', column.key)"
                        >
                          权重降序
                        </Button>
                      </template>
                      <div class="column-filter-actions">
                        <Button size="small" @click="clearSettingColumnFilter(column.key)">
                          清空
                        </Button>
                        <Button
                          :loading="settingLoading"
                          size="small"
                          type="primary"
                          @click="applySettingColumnFilter(column.key)"
                        >
                          查询
                        </Button>
                      </div>
                    </div>
                  </template>
                  <Button
                    class="column-filter-button"
                    :class="{ 'column-filter-button--active': hasSettingColumnFilter(column.key) }"
                    size="small"
                    type="text"
                    @click.stop
                  >
                    <SearchIcon class="filter-icon-svg" />
                  </Button>
                </Popover>
                <span>{{ column.title }}</span>
              </div>
            </template>
            <template v-else>
              {{ column.title }}
            </template>
          </template>
          <template #bodyCell="{ column, record }">
            <template v-if="column.key === 'giftPhoto'">
              <div class="week-star-gift">
                <Image :src="getAccessImgUrl(record.giftPhoto)" class="gift-image" />
              </div>
            </template>
            <template v-else-if="column.key === 'del'">
              <Switch
                :checked="!record.del"
                @change="record.del = !$event; handleSwitch(record)"
              />
            </template>
            <template v-else-if="column.key === 'createTime'">
              {{ formatDate(record.createTime) }}
            </template>
            <template v-else-if="column.key === 'giftTab'">
              {{ getGiftTabName(record.giftTab) }}
            </template>
            <template v-else-if="column.key === 'cpRelationType'">
              {{ record.giftTab === 'CP' ? getCpRelationTypeName(record.cpRelationType || 'CP') : '-' }}
            </template>
            <template v-else-if="column.key === 'regionNameStr'">
              <Tooltip :title="stringifyCellValue(record.regionNameStr)">
                <span class="region-cell">
                  {{ stringifyCellValue(record.regionNameStr) }}
                </span>
              </Tooltip>
            </template>
            <template v-else-if="column.key === 'userBaseInfo'">
              {{ record.userBaseInfo?.actualAccount || record.userBaseInfo?.id || '-' }}
            </template>
            <template v-else-if="column.key === 'sort'">
              <Input
                v-if="editingGiftSortId === String(record.id || '')"
                :ref="(element: any) => setGiftSortInputRef(record.id, element)"
                v-model:value="editingGiftSortValue"
                class="gift-sort-input"
                size="small"
                @blur="saveGiftSort(record)"
                @keyup.enter="saveGiftSort(record)"
                @keyup.esc="cancelGiftSortEdit"
              />
              <button
                v-else
                class="gift-sort-value"
                type="button"
                @click="startGiftSortEdit(record)"
              >
                {{ stringifyCellValue(record.sort) }}
              </button>
            </template>
            <template v-else-if="column.key === 'actions'">
              <Button size="small" type="link" @click="openGiftEdit(record)">
                编辑
              </Button>
            </template>
            <template v-else>
              {{ stringifyCellValue(getColumnValue(record, column)) }}
            </template>
          </template>
        </AdminConfigTable>
      </div>

      <div v-else-if="activeTab === 'weekStar'">
        <Space class="toolbar" wrap>
          <SysOriginSelect
            v-model:value="weekStarQuery.sysOrigin"
            style="width: 160px"
            @change="loadWeekStar(true)"
            :options="sysOriginOptions"
          />
          <Button type="primary" @click="openWeekStarModal">
            新增
          </Button>
          <Tag color="warning">注意：周星正常运行切换最少需要配置 3 组礼物</Tag>
        </Space>

        <Table
          :columns="weekStarColumns"
          :data-source="weekStarList"
          :loading="weekStarLoading"
          :pagination="false"
          row-key="id"
          :scroll="{ x: 920 }"
        >
          <template #bodyCell="{ column, record }">
            <template v-if="column.key === 'sysGiftConfigs'">
              <div class="week-star-gifts">
                <div
                  v-for="item in record.sysGiftConfigs || []"
                  :key="item.id"
                  class="week-star-gift"
                >
                  <Image :src="getAccessImgUrl(item.giftPhoto)" class="gift-image" />
                  <div>{{ item.giftCandy || 0 }}</div>
                </div>
              </div>
            </template>
            <template v-else-if="column.key === 'type'">
              {{
                record.type === 'THIS_WEEK'
                  ? '当前'
                  : record.type === 'LAST_WEEK'
                    ? '上周'
                    : record.type === 'NEXT_WEEK'
                      ? '下周'
                      : '-'
              }}
            </template>
            <template v-else-if="column.key === 'actions'">
              <Button
                danger
                size="small"
                type="link"
                :disabled="record.type !== 'NONE' || weekStarList.length <= 3"
                @click="handleWeekStarDelete(record)"
              >
                删除
              </Button>
            </template>
          </template>
        </Table>

        <div class="pager">
          <Pagination
            :current="weekStarQuery.cursor"
            :page-size="weekStarQuery.limit"
            :total="weekStarTotal"
            show-size-changer
            @change="handleWeekStarPageChange"
            @show-size-change="handleWeekStarPageChange"
          />
        </div>
      </div>

      <div v-else class="cp-panel">
        <Space class="toolbar" wrap>
          <SysOriginSelect
            v-model:value="cpForm.sysOrigin"
            style="width: 160px"
            @change="loadCp"
            :options="sysOriginOptions"
          />
          <Input
            v-model:value="cpForm.giftId"
            placeholder="礼物ID"
            style="width: 180px"
          />
          <Button :loading="cpSaving || cpLoading" type="primary" @click="handleCpSave">
            保存
          </Button>
        </Space>
      </div>
    </Card>

    <GiftFormModal
      :open="giftFormOpen"
      :row="activeGiftRow"
      :sys-origin="settingQuery.sysOrigin"
      @close="giftFormOpen = false"
      @success="loadSetting(true)"
    />

    <GiftBatchDrawer
      :initial-sys-origin="settingQuery.sysOrigin"
      :open="giftBatchOpen"
      :sys-origin-options="sysOriginOptions"
      @close="giftBatchOpen = false"
      @success="loadSetting(true)"
    />

    <Modal
      :confirm-loading="batchEditSaving"
      :open="batchEditOpen"
      destroy-on-close
      title="批量修改礼物"
      @cancel="batchEditOpen = false"
      @ok="handleBatchEditSubmit"
    >
      <div class="batch-edit-summary">
        已选择 {{ selectedGiftCount }} 个礼物，只会修改勾选字段。
      </div>
      <div class="batch-edit-grid">
        <div class="batch-edit-field">
          <Checkbox v-model:checked="batchEditFields.giftTab">礼物类型</Checkbox>
          <Select
            v-model:value="batchEditForm.giftTab"
            :disabled="!batchEditFields.giftTab"
            :options="GIFT_CONFIG_TAB_OPTIONS.map((item) => ({ label: `${item.name}`, value: item.value as any }))"
            option-label-prop="label"
          />
        </div>
        <div class="batch-edit-field">
          <Checkbox v-model:checked="batchEditFields.cpRelationType">CP礼物类型</Checkbox>
          <Select
            v-model:value="batchEditForm.cpRelationType"
            :disabled="!batchEditFields.cpRelationType"
            :options="CP_RELATION_TYPE_OPTIONS.map((item) => ({ label: `${item.name}`, value: item.value as any }))"
            option-label-prop="label"
          />
        </div>
        <div class="batch-edit-field">
          <Checkbox v-model:checked="batchEditFields.type">收费类型</Checkbox>
          <Select
            v-model:value="batchEditForm.type"
            :disabled="!batchEditFields.type"
            :options="GIFT_CHARGE_TYPE_OPTIONS"
            option-label-prop="label"
          />
        </div>
        <div class="batch-edit-field batch-edit-field--wide">
          <Checkbox v-model:checked="batchEditFields.specialList">特效</Checkbox>
          <Select
            v-model:value="batchEditForm.specialList"
            :disabled="!batchEditFields.specialList"
            :options="giftSpecialOptions"
            mode="multiple"
            option-label-prop="label"
            placeholder="请选择特效"
          />
        </div>
        <div class="batch-edit-field">
          <Checkbox v-model:checked="batchEditFields.giftCandy">金币</Checkbox>
          <InputNumber
            v-model:value="batchEditForm.giftCandy"
            :disabled="!batchEditFields.giftCandy"
            :min="0"
            style="width: 100%"
          />
        </div>
        <div class="batch-edit-field">
          <Checkbox v-model:checked="batchEditFields.giftIntegral">积分</Checkbox>
          <InputNumber
            v-model:value="batchEditForm.giftIntegral"
            :disabled="!batchEditFields.giftIntegral"
            :min="0"
            style="width: 100%"
          />
        </div>
        <div class="batch-edit-field">
          <Checkbox v-model:checked="batchEditFields.sort">排序权重</Checkbox>
          <InputNumber
            v-model:value="batchEditForm.sort"
            :disabled="!batchEditFields.sort"
            style="width: 100%"
          />
        </div>
        <div class="batch-edit-field">
          <Checkbox v-model:checked="batchEditFields.del">上/下架</Checkbox>
          <Select
            v-model:value="batchEditForm.del"
            :disabled="!batchEditFields.del"
            :options="SHELF_OPTIONS.map((item) => ({ label: `${item.label}`, value: item.value as any }))"
            option-label-prop="label"
          />
        </div>
      </div>
    </Modal>

    <Modal
      :confirm-loading="addRegionSaving"
      :open="addRegionOpen"
      destroy-on-close
      title="添加全部礼物区域"
      @cancel="addRegionOpen = false"
      @ok="handleAddRegionSubmit"
    >
      <Space direction="vertical" style="width: 100%">
        <div class="transfer-warning">
          确认后，会在当前平台所有礼物现有区域基础上追加所选区域，已有该区域的礼物不会重复添加。
        </div>
        <Select
          v-model:value="addRegionForm.regionId"
          :options="regionOptions"
          option-label-prop="label"
          placeholder="请选择要追加的区域"
          show-search
          style="width: 100%"
        />
      </Space>
    </Modal>

    <Modal
      :confirm-loading="weekStarSaving"
      :open="weekStarOpen"
      destroy-on-close
      title="添加周星礼物组"
      @cancel="weekStarOpen = false"
      @ok="handleWeekStarSubmit"
    >
      <Space direction="vertical" style="width: 100%">
        <SysOriginSelect
          v-model:value="weekStarForm.sysOrigin"
          disabled
          :options="sysOriginOptions"
        />
        <Select
          v-model:value="weekStarForm.giftOne"
          :options="getWeekStarSelectOptions(String(weekStarForm.giftOne || ''))"
          option-label-prop="label"
          placeholder="礼物1"
        />
        <Select
          v-model:value="weekStarForm.giftTwo"
          :options="getWeekStarSelectOptions(String(weekStarForm.giftTwo || ''))"
          option-label-prop="label"
          placeholder="礼物2"
        />
        <Select
          v-model:value="weekStarForm.giftThree"
          :options="getWeekStarSelectOptions(String(weekStarForm.giftThree || ''))"
          option-label-prop="label"
          placeholder="礼物3"
        />
      </Space>
    </Modal>
  </Page>
</template>

<style scoped>
.toolbar {
  margin-bottom: 12px;
}

.gift-page-card {
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  height: 100%;
}

.gift-page-card :deep(.ant-card-body) {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0;
  padding: 16px;
}

.gift-page-card :deep(.ant-tabs-nav) {
  margin: 0 0 8px;
}

.gift-setting-panel {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  min-height: 0;
}

.gift-setting-table {
  flex: 1 1 auto;
  min-height: 360px;
}

.region-cell {
  display: block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.column-title {
  align-items: center;
  display: inline-flex;
  gap: 6px;
  min-width: 0;
  white-space: nowrap;
}

.column-title--actions {
  justify-content: center;
  width: 100%;
}

.column-filter-button,
.filter-reset-button {
  align-items: center;
  color: rgb(102 112 133);
  display: inline-flex;
  height: 22px;
  justify-content: center;
  padding: 0;
  width: 22px;
}

.column-filter-button:hover,
.filter-reset-button:hover {
  background: rgb(242 244 247);
  color: rgb(23 92 211);
}

.column-filter-button--active {
  background: rgb(230 240 255);
  color: rgb(22 119 255);
}

.filter-icon-svg {
  height: 14px;
  width: 14px;
}

.column-filter-panel {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 220px;
}

.column-filter-panel :deep(.ant-input),
.column-filter-panel :deep(.ant-input-number),
.column-filter-panel :deep(.ant-select) {
  width: 100%;
}

.column-filter-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
}

:global(.gift-filter-popover .ant-popover-inner-content) {
  padding: 12px;
}

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

.gift-image {
  border-radius: 12px;
  height: 52px;
  object-fit: cover;
  width: 52px;
}

.gift-sort-input {
  max-width: 72px;
}

.gift-sort-value {
  min-width: 48px;
  padding: 2px 6px;
  color: inherit;
  text-align: left;
  cursor: text;
  background: transparent;
  border: 0;
  border-radius: 4px;
}

.gift-sort-value:hover {
  background: #f1f5f9;
}

.week-star-gifts {
  display: flex;
  gap: 12px;
}

.week-star-gift {
  align-items: center;
  display: grid;
  gap: 6px;
  justify-items: center;
}

.cp-panel {
  min-height: 120px;
}

.transfer-warning {
  color: #dc2626;
  line-height: 22px;
}

.batch-edit-summary {
  color: #475569;
  font-size: 13px;
  margin-bottom: 12px;
}

.batch-edit-grid {
  display: grid;
  gap: 12px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.batch-edit-field {
  display: grid;
  gap: 6px;
}

.batch-edit-field--wide {
  grid-column: 1 / -1;
}

:global(.gift-page-content) {
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden !important;
  padding: 16px !important;
}
</style>
