<script lang="ts" setup>
/**
 * VIP 功能字典列表：维护功能码，并支持反绑「开放给哪些会员等级」
 */
import { onMounted, reactive, ref } from 'vue';

import { Page, useVbenModal } from '@vben/common-ui';

import {
  Button,
  Card,
  Empty,
  Input,
  Pagination,
  Select,
  Tag,
  message,
} from 'ant-design-vue';

import { TableAction } from '#/components/table-action';

import { deleteVipFeature, getVipFeatureList } from './api';
import BindLevelsModal from './components/bind-levels-modal.vue';
import FormModal from './components/modal.vue';
import { STATUS_OPTIONS } from './config/constants';

defineOptions({ name: 'VipFeature' });

const loading = ref(false);
const list = ref<any[]>([]);
const total = ref(0);
const page = reactive({ current: 1, pageSize: 12 });
const filters = reactive({
  code: '',
  name: '',
  status: undefined as number | undefined,
});

const [FormModalComp, formModalApi] = useVbenModal({
  connectedComponent: FormModal,
});
const [BindLevelsModalComp, bindLevelsModalApi] = useVbenModal({
  connectedComponent: BindLevelsModal,
});

async function loadList() {
  loading.value = true;
  try {
    const res = await getVipFeatureList({
      page: page.current,
      pageSize: page.pageSize,
      code: filters.code || undefined,
      name: filters.name || undefined,
      status: filters.status,
    });
    list.value = res?.items || [];
    total.value = Number(res?.total || 0);
  } finally {
    loading.value = false;
  }
}

function onSearch() {
  page.current = 1;
  loadList();
}

function onReset() {
  filters.code = '';
  filters.name = '';
  filters.status = undefined;
  onSearch();
}

const showModal = (data: any = {}, isUpdate = false) => {
  formModalApi.setData({
    values: data,
    update: isUpdate,
    gridApi: { query: loadList, reload: loadList },
  });
  formModalApi.open();
};

/**
 * 已绑等级展示文案：同名等级（如多档「黄金会员」）需同时带上 code（V1/V2…）才能区分
 */
function formatBoundLevelLabel(lv: Record<string, any>) {
  const name = String(lv?.name || '').trim();
  const code = String(lv?.code || '').trim();
  if (name && code) {
    return `${name}（${code}）`;
  }
  return name || code || '—';
}

/** 打开反绑等级弹窗 */
function openBindLevels(item: Record<string, any>) {
  bindLevelsModalApi.setData({
    feature: item,
    onSaved: loadList,
  });
  bindLevelsModalApi.open();
}

const handleDelete = (id: number) => {
  deleteVipFeature({ ids: [id] }).then(() => {
    message.success('删除成功');
    loadList();
  });
};

onMounted(loadList);
</script>
<template>
  <Page auto-content-height title="VIP功能字典">
    <FormModalComp />
    <BindLevelsModalComp />
    <div class="p-4">
      <div class="mb-4 flex flex-wrap items-center gap-3">
        <Input
          v-model:value="filters.code"
          allow-clear
          placeholder="功能编码"
          class="w-40"
          @press-enter="onSearch"
        />
        <Input
          v-model:value="filters.name"
          allow-clear
          placeholder="功能名称"
          class="w-40"
          @press-enter="onSearch"
        />
        <Select
          v-model:value="filters.status"
          allow-clear
          placeholder="状态"
          class="w-28"
          :options="STATUS_OPTIONS"
        />
        <Button type="primary" @click="onSearch">查询</Button>
        <Button @click="onReset">重置</Button>
        <TableAction
          :actions="[
            {
              label: '新增功能',
              type: 'primary',
              onClick: () => showModal({}, false),
            },
          ]"
        />
      </div>
      <div v-if="list.length" class="grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-3">
        <Card v-for="item in list" :key="item.id" size="small" :loading="loading">
          <template #title>
            <span class="font-medium">{{ item.name }}</span>
            <Tag class="ml-2" :color="item.status === 1 ? 'success' : 'default'">
              {{ item.status_txt }}
            </Tag>
          </template>
          <template #extra>
            <TableAction
              :actions="[
                { label: '绑定等级', onClick: () => openBindLevels(item) },
                { label: '编辑', onClick: () => showModal(item, true) },
                {
                  label: '删除',
                  danger: true,
                  popConfirm: {
                    title: '确认删除该功能？',
                    confirm: () => handleDelete(item.id),
                  },
                },
              ]"
            />
          </template>
          <div class="text-sm text-[hsl(var(--muted-foreground))]">
            <div>编码：{{ item.code }}</div>
            <div class="mt-1">说明：{{ item.description || '-' }}</div>
            <div class="mt-1">排序：{{ item.sort }}</div>
            <div class="mt-2">
              <div class="mb-1">已绑等级：</div>
              <div
                v-if="item.bound_levels && item.bound_levels.length"
                class="flex flex-wrap gap-2"
              >
                <div
                  v-for="lv in item.bound_levels"
                  :key="lv.id"
                  class="bound-vip-chip"
                  :title="formatBoundLevelLabel(lv)"
                >
                  <img
                    v-if="lv.badge_url"
                    :src="lv.badge_url"
                    :alt="formatBoundLevelLabel(lv)"
                    class="bound-vip-chip__img"
                  />
                  <span v-else class="bound-vip-chip__fallback">{{
                    (lv.code || lv.name || '?').slice(0, 1)
                  }}</span>
                  <span class="bound-vip-chip__text">
                    <span class="bound-vip-chip__name">{{
                      lv.name || lv.code || '—'
                    }}</span>
                    <span v-if="lv.code" class="bound-vip-chip__code">{{
                      lv.code
                    }}</span>
                  </span>
                </div>
              </div>
              <span v-else class="text-xs">未绑定任何会员等级</span>
            </div>
          </div>
        </Card>
      </div>
      <Empty v-else description="暂无功能，请先新增或执行 SQL 种子" />
      <div class="mt-4 flex justify-end">
        <Pagination
          v-model:current="page.current"
          v-model:page-size="page.pageSize"
          :total="total"
          show-size-changer
          @change="loadList"
        />
      </div>
    </div>
  </Page>
</template>

<style scoped>
.bound-vip-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 8px 4px 4px;
  border-radius: 8px;
  border: 1px solid hsl(var(--border));
  background: hsl(var(--muted) / 0.25);
}
.bound-vip-chip__img {
  width: 28px;
  height: 28px;
  object-fit: contain;
}
.bound-vip-chip__fallback {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 600;
  background: hsl(var(--muted) / 0.5);
  color: hsl(var(--muted-foreground));
}
.bound-vip-chip__text {
  display: inline-flex;
  flex-direction: column;
  min-width: 0;
  line-height: 1.2;
}
.bound-vip-chip__name {
  font-size: 12px;
  color: hsl(var(--foreground));
  max-width: 96px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bound-vip-chip__code {
  font-size: 11px;
  color: hsl(var(--muted-foreground));
}
</style>
