<template>
  <a-page-header :title="getPageTitle()" @back="() => $router.go(-1)">
    <template #extra>
      <a-space>
        <a-button type="primary" @click="openEdit()">
          <template #icon>
            <PlusOutlined />
          </template>
          新增优惠券
        </a-button>
        <a-button @click="reload()">
          <template #icon>
            <ReloadOutlined />
          </template>
          刷新
        </a-button>
      </a-space>
    </template>

    <a-card :bordered="false" :body-style="{ padding: '16px' }">
      <!-- 搜索区域 -->
      <div class="search-container">
        <a-form layout="inline" :model="searchForm" class="search-form">
          <a-form-item label="优惠券名称">
            <a-input
              v-model:value="searchForm.name"
              placeholder="请输入优惠券名称"
              allow-clear
              style="width: 200px"
            />
          </a-form-item>
          <a-form-item label="优惠券类型">
            <a-select
              v-model:value="searchForm.type"
              placeholder="请选择类型"
              allow-clear
              style="width: 150px"
            >
              <a-select-option :value="10">满减券</a-select-option>
              <a-select-option :value="20">折扣券</a-select-option>
              <a-select-option :value="30">免费券</a-select-option>
              <a-select-option :value="40">无门槛券</a-select-option>
              <a-select-option :value="50">场地使用券</a-select-option>
            </a-select>
          </a-form-item>
          <a-form-item label="到期类型">
            <a-select
              v-model:value="searchForm.expireType"
              placeholder="请选择到期类型"
              allow-clear
              style="width: 150px"
            >
              <a-select-option :value="10">领取后生效</a-select-option>
              <a-select-option :value="20">固定时间</a-select-option>
            </a-select>
          </a-form-item>
          <a-form-item label="是否过期">
            <a-select
              v-model:value="searchForm.isExpire"
              placeholder="请选择状态"
              allow-clear
              style="width: 120px"
            >
              <a-select-option :value="0">未过期</a-select-option>
              <a-select-option :value="1">已过期</a-select-option>
            </a-select>
          </a-form-item>
          <a-form-item>
            <a-space>
              <a-button type="primary" @click="handleSearch">
                <template #icon>
                  <SearchOutlined />
                </template>
                搜索
              </a-button>
              <a-button @click="handleReset">
                <template #icon>
                  <ClearOutlined />
                </template>
                重置
              </a-button>
            </a-space>
          </a-form-item>
        </a-form>
      </div>

      <!-- 批量操作区域 -->
      <div v-if="selection.length > 0" class="batch-actions">
        <a-alert
          :message="`已选择 ${selection.length} 项`"
          type="info"
          show-icon
          style="margin-bottom: 16px"
        >
          <template #action>
            <a-space>
              <a-button size="small" @click="clearSelection">取消选择</a-button>
              <a-popconfirm
                title="确定要删除选中的优惠券吗？"
                @confirm="removeBatch"
              >
                <a-button size="small" danger>批量删除</a-button>
              </a-popconfirm>
            </a-space>
          </template>
        </a-alert>
      </div>

      <!-- 表格 -->
      <ele-pro-table
        ref="tableRef"
        row-key="id"
        :columns="columns"
        :datasource="datasource"
        :customRow="customRow"
        :row-selection="rowSelection"
        :scroll="{ x: 1800 }"
        tool-class="ele-toolbar-form"
        class="coupon-table"
      >
        <template #bodyCell="{ column, record }">
          <template v-if="column.key === 'name'">
            <div class="coupon-name">
              <a-typography-text strong>{{ record.name }}</a-typography-text>
              <div class="coupon-description">{{
                record.description || '暂无描述'
              }}</div>
            </div>
          </template>

          <template v-if="column.key === 'type'">
            <a-tag :color="getCouponTypeColor(record.type)">
              {{ getCouponTypeText(record.type) }}
            </a-tag>
          </template>

          <template v-if="column.key === 'value'">
            <div class="coupon-value">
              <template v-if="record.type === 10">
                <span class="value-amount"
                  >¥{{ Number(record.reducePrice).toFixed(2) || '0.00' }}</span
                >
                <div class="value-condition"
                  >满¥{{
                    Number(record.minPrice).toFixed(2) || '0.00'
                  }}可用</div
                >
              </template>
              <template v-else-if="record.type === 20">
                <span class="value-discount">{{ record.discount }}折</span>
                <div class="value-condition"
                  >满¥{{
                    Number(record.minPrice)?.toFixed(2) || '0.00'
                  }}可用</div
                >
              </template>
              <template v-else-if="record.type === 30">
                <span class="value-free">免费券</span>
                <div class="value-condition"
                  >满¥{{
                    Number(record.minPrice)?.toFixed(2) || '0.00'
                  }}可用</div
                >
              </template>
              <template v-else-if="record.type === 40">
                <span class="value-amount" style="color: #1890ff"
                  >¥{{ Number(record.reducePrice).toFixed(2) || '0.00' }}</span
                >
                <div class="value-condition">无门槛</div>
              </template>
              <template v-else-if="record.type === 50">
                <span class="value-free" style="color: #13c2c2">场地券</span>
                <div class="value-condition">
                  {{ record.useCount === -1 ? '无限次' : record.useCount + '次' }}
                  <template v-if="record.useDuration"
                    >/{{ record.useDuration }}分钟</template
                  >
                </div>
              </template>
            </div>
          </template>

          <template v-if="column.key === 'expireInfo'">
            <div class="expire-info">
              <a-tag :color="record.expireType === 10 ? 'blue' : 'green'">
                {{ record.expireType === 10 ? '领取后生效' : '固定时间' }}
              </a-tag>
              <div class="expire-detail">
                <template v-if="record.expireType === 10">
                  {{ record.expireDay }}天有效
                </template>
                <template v-else>
                  {{ formatDate(record.startTime) }} 至
                  {{ formatDate(record.endTime) }}
                </template>
              </div>
            </div>
          </template>

          <template v-if="column.key === 'applyRange'">
            <a-tag :color="getApplyRangeColor(record.applyRange)">
              {{ getApplyRangeText(record.applyRange) }}
            </a-tag>
          </template>

          <template v-if="column.key === 'receiveTarget'">
            <a-tag :color="getReceiveTargetColor(record.receiveTarget || 0)">
              {{ getReceiveTargetText(record.receiveTarget || 0) }}
            </a-tag>
            <template v-if="record.receiveTarget === 3 && record.receiveUserIds">
              <div style="color: #999; font-size: 12px">
                已指定 {{ JSON.parse(record.receiveUserIds).length }} 人
              </div>
            </template>
          </template>

          <template v-if="column.key === 'usage'">
            <div class="usage-info">
              <a-progress
                :percent="getUsagePercent(record)"
                :stroke-color="getUsageColor(record)"
                size="small"
              />
              <div class="usage-text">
                已发放: {{ record.issuedCount || 0 }}
                <template v-if="record.totalCount !== -1">
                  / {{ record.totalCount }}
                </template>
                <template v-else> (无限制) </template>
              </div>
            </div>
          </template>

          <template v-if="column.key === 'isExpire'">
            <a-tag :color="record.isExpire === 0 ? 'success' : 'error'">
              {{ record.isExpire === 0 ? '未过期' : '已过期' }}
            </a-tag>
          </template>

          <template v-if="column.key === 'action'">
            <a-space>
              <a-tooltip title="编辑">
                <a-button type="link" size="small" @click="openEdit(record)">
                  <template #icon>
                    <EditOutlined />
                  </template>
                </a-button>
              </a-tooltip>
              <a-tooltip title="复制">
                <a-button type="link" size="small" @click="copyRecord(record)">
                  <template #icon>
                    <CopyOutlined />
                  </template>
                </a-button>
              </a-tooltip>
              <a-popconfirm
                title="确定要删除此优惠券吗？"
                @confirm="remove(record)"
              >
                <a-tooltip title="删除">
                  <a-button type="link" size="small" danger>
                    <template #icon>
                      <DeleteOutlined />
                    </template>
                  </a-button>
                </a-tooltip>
              </a-popconfirm>
            </a-space>
          </template>
        </template>
      </ele-pro-table>
    </a-card>

    <!-- 编辑弹窗 -->
    <ShopCouponEdit v-model:visible="showEdit" :data="current" @done="reload" />
  </a-page-header>
</template>

<script lang="ts" setup>
  import { createVNode, ref, reactive, computed } from 'vue';
  import { message, Modal } from 'ant-design-vue';
  import {
    ExclamationCircleOutlined,
    PlusOutlined,
    ReloadOutlined,
    SearchOutlined,
    ClearOutlined,
    EditOutlined,
    DeleteOutlined,
    CopyOutlined
  } from '@ant-design/icons-vue';
  import type { EleProTable } from 'ele-admin-pro';
  import { toDateString } from 'ele-admin-pro';
  import type {
    DatasourceFunction,
    ColumnItem
  } from 'ele-admin-pro/es/ele-pro-table/types';
  import { getPageTitle } from '@/utils/common';
  import ShopCouponEdit from './components/shopCouponEdit.vue';
  import {
    pageShopCoupon,
    removeShopCoupon,
    removeBatchShopCoupon
  } from '@/api/shop/shopCoupon';
  import type {
    ShopCoupon,
    ShopCouponParam
  } from '@/api/shop/shopCoupon/model';

  // 表格实例
  const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);

  // 表格选中数据
  const selection = ref<ShopCoupon[]>([]);
  // 当前编辑数据
  const current = ref<ShopCoupon | null>(null);
  // 是否显示编辑弹窗
  const showEdit = ref(false);
  // 加载状态
  const loading = ref(false);

  // 搜索表单
  const searchForm = reactive<ShopCouponParam>({
    keywords: '',
    name: undefined,
    type: undefined
  });

  // 表格数据源
  const datasource: DatasourceFunction = ({
    page,
    limit,
    where,
    orders,
    filters
  }) => {
    const params = {
      ...where,
      ...searchForm,
      ...orders,
      page,
      limit
    };

    if (filters) {
      Object.assign(params, filters);
    }

    return pageShopCoupon(params);
  };

  // 行选择配置
  const rowSelection = computed(() => ({
    selectedRowKeys: selection.value.map((item) => item.id),
    onChange: (
      selectedRowKeys: (string | number)[],
      selectedRows: ShopCoupon[]
    ) => {
      selection.value = selectedRows;
    },
    onSelect: (record: ShopCoupon, selected: boolean) => {
      if (selected) {
        selection.value.push(record);
      } else {
        const index = selection.value.findIndex(
          (item) => item.id === record.id
        );
        if (index > -1) {
          selection.value.splice(index, 1);
        }
      }
    },
    onSelectAll: (
      selected: boolean,
      selectedRows: ShopCoupon[],
      changeRows: ShopCoupon[]
    ) => {
      if (selected) {
        changeRows.forEach((row) => {
          if (!selection.value.find((item) => item.id === row.id)) {
            selection.value.push(row);
          }
        });
      } else {
        changeRows.forEach((row) => {
          const index = selection.value.findIndex((item) => item.id === row.id);
          if (index > -1) {
            selection.value.splice(index, 1);
          }
        });
      }
    }
  }));

  // 表格列配置
  const columns = ref<ColumnItem[]>([
    {
      title: 'ID',
      dataIndex: 'id',
      key: 'id',
      align: 'center',
      width: 80,
      fixed: 'left'
    },
    {
      title: '优惠券信息',
      dataIndex: 'name',
      key: 'name',
      align: 'left',
      width: 250,
      fixed: 'left',
      ellipsis: true
    },
    {
      title: '类型',
      dataIndex: 'type',
      key: 'type',
      align: 'center',
      width: 100
    },
    {
      title: '优惠价值',
      dataIndex: 'value',
      key: 'value',
      align: 'center',
      width: 150
    },
    {
      title: '有效期信息',
      dataIndex: 'expireInfo',
      key: 'expireInfo',
      align: 'center',
      width: 180
    },
    {
      title: '适用范围',
      dataIndex: 'applyRange',
      key: 'applyRange',
      align: 'center',
      width: 120
    },
    {
      title: '发放对象',
      dataIndex: 'receiveTarget',
      key: 'receiveTarget',
      align: 'center',
      width: 120
    },
    {
      title: '使用情况',
      dataIndex: 'usage',
      key: 'usage',
      align: 'center',
      width: 150
    },
    {
      title: '每人限领',
      dataIndex: 'limitPerUser',
      key: 'limitPerUser',
      align: 'center',
      width: 100,
      customRender: ({ text }) => (text === -1 ? '无限制' : text)
    },
    {
      title: '状态',
      dataIndex: 'isExpire',
      key: 'isExpire',
      align: 'center',
      width: 100
    },
    {
      title: '创建时间',
      dataIndex: 'createTime',
      key: 'createTime',
      align: 'center',
      width: 120,
      sorter: true,
      ellipsis: true,
      customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd')
    },
    {
      title: '操作',
      key: 'action',
      width: 150,
      fixed: 'right',
      align: 'center',
      hideInSetting: true
    }
  ]);

  // 工具方法
  const getCouponTypeText = (type: number) => {
    const typeMap: Record<number, string> = {
      10: '满减券',
      20: '折扣券',
      30: '免费券',
      40: '无门槛券',
      50: '场地使用券'
    };
    return typeMap[type] || '未知';
  };

  const getCouponTypeColor = (type: number) => {
    const colorMap: Record<number, string> = {
      10: 'red',
      20: 'orange',
      30: 'green',
      40: 'blue',
      50: 'cyan'
    };
    return colorMap[type] || 'default';
  };

  const getReceiveTargetText = (target: number) => {
    const targetMap: Record<number, string> = {
      0: '全部用户',
      1: '仅会员',
      2: '仅非会员',
      3: '指定用户'
    };
    return targetMap[target] || '全部';
  };

  const getReceiveTargetColor = (target: number) => {
    const colorMap: Record<number, string> = {
      0: 'default',
      1: 'gold',
      2: 'geekblue',
      3: 'magenta'
    };
    return colorMap[target] || 'default';
  };

  const getApplyRangeText = (range: number) => {
    const rangeMap = {
      10: '全部商品',
      20: '指定商品',
      30: '指定分类'
    };
    return rangeMap[range as keyof typeof rangeMap] || '未知';
  };

  const getApplyRangeColor = (range: number) => {
    const colorMap = {
      10: 'blue',
      20: 'purple',
      30: 'cyan'
    };
    return colorMap[range as keyof typeof colorMap] || 'default';
  };

  const formatDate = (dateStr: string) => {
    return dateStr ? toDateString(dateStr, 'yyyy-MM-dd') : '-';
  };

  const getUsagePercent = (record: ShopCoupon) => {
    if (record.totalCount === -1) return 0;
    return Math.round(
      ((record.issuedCount || 0) / Number(record.totalCount)) * 100
    );
  };

  const getUsageColor = (record: ShopCoupon) => {
    const percent = getUsagePercent(record);
    if (percent >= 90) return '#ff4d4f';
    if (percent >= 70) return '#faad14';
    return '#52c41a';
  };

  /* 搜索 */
  const reload = (where?: ShopCouponParam) => {
    selection.value = [];
    tableRef?.value?.reload({ where: where });
  };

  /* 处理搜索 */
  const handleSearch = () => {
    reload();
  };

  /* 重置搜索 */
  const handleReset = () => {
    Object.assign(searchForm, {
      name: '',
      type: undefined,
      expireType: undefined,
      isExpire: undefined
    });
    reload();
  };

  /* 清除选择 */
  const clearSelection = () => {
    selection.value = [];
  };

  /* 打开编辑弹窗 */
  const openEdit = (row?: ShopCoupon) => {
    current.value = row ?? null;
    showEdit.value = true;
  };

  /* 复制记录 */
  const copyRecord = (record: ShopCoupon) => {
    const copyData = {
      ...record,
      id: undefined,
      name: `${record.name}_副本`,
      createTime: undefined,
      updateTime: undefined,
      issuedCount: 0
    };
    current.value = copyData;
    showEdit.value = true;
    message.success('已复制优惠券信息，请修改后保存');
  };

  /* 删除单个 */
  const remove = (row: ShopCoupon) => {
    if (row.issuedCount && row.issuedCount > 0) {
      message.warning('该优惠券已有用户领取，无法删除');
      return;
    }

    const hide = message.loading('删除中...', 0);
    removeShopCoupon(row.id)
      .then((msg) => {
        hide();
        message.success(msg);
        reload();
      })
      .catch((e) => {
        hide();
        message.error(e.message);
      });
  };

  /* 批量删除 */
  const removeBatch = () => {
    if (!selection.value.length) {
      message.error('请至少选择一条数据');
      return;
    }

    // 检查是否有已发放的优惠券
    const issuedCoupons = selection.value.filter(
      (item) => item.issuedCount && item.issuedCount > 0
    );
    if (issuedCoupons.length > 0) {
      message.warning(
        `选中的优惠券中有 ${issuedCoupons.length} 个已被用户领取，无法删除`
      );
      return;
    }

    Modal.confirm({
      title: '批量删除确认',
      content: `确定要删除选中的 ${selection.value.length} 个优惠券吗？此操作不可恢复。`,
      icon: createVNode(ExclamationCircleOutlined),
      maskClosable: true,
      okText: '确定删除',
      okType: 'danger',
      cancelText: '取消',
      onOk: () => {
        const hide = message.loading('批量删除中...', 0);
        removeBatchShopCoupon(selection.value.map((d) => d.id))
          .then((msg) => {
            hide();
            message.success(msg);
            selection.value = [];
            reload();
          })
          .catch((e) => {
            hide();
            message.error(e.message);
          });
      }
    });
  };

  /* 自定义行属性 */
  const customRow = (record: ShopCoupon) => {
    return {
      // 行点击事件
      onClick: () => {
        // console.log(record);
      },
      // 行双击事件
      onDblclick: () => {
        openEdit(record);
      },
      // 行样式
      class: record.isExpire === 1 ? 'expired-row' : ''
    };
  };
</script>

<script lang="ts">
  export default {
    name: 'ShopCoupon'
  };
</script>

<style lang="less" scoped>
  .shop-coupon-container {
    .search-container {
      background: #fafafa;
      padding: 16px;
      border-radius: 6px;
      margin-bottom: 16px;

      .search-form {
        .ant-form-item {
          margin-bottom: 8px;
        }
      }
    }

    .batch-actions {
      margin-bottom: 16px;
    }

    .coupon-table {
      .coupon-name {
        text-align: left;

        .coupon-description {
          font-size: 12px;
          color: #999;
          margin-top: 4px;
        }
      }

      .coupon-value {
        .value-amount {
          font-size: 16px;
          font-weight: bold;
          color: #f5222d;
        }

        .value-discount {
          font-size: 16px;
          font-weight: bold;
          color: #fa8c16;
        }

        .value-free {
          font-size: 14px;
          font-weight: bold;
          color: #52c41a;
        }

        .value-condition {
          font-size: 12px;
          color: #666;
          margin-top: 2px;
        }
      }

      .expire-info {
        .expire-detail {
          font-size: 12px;
          color: #666;
          margin-top: 4px;
        }
      }

      .usage-info {
        .usage-text {
          font-size: 12px;
          color: #666;
          margin-top: 4px;
        }
      }

      .expired-row {
        background-color: #fff2f0;

        td {
          opacity: 0.7;
        }
      }
    }
  }

  :deep(.ant-table) {
    .ant-table-tbody > tr:hover > td {
      background-color: #e6f7ff;
    }
  }

  :deep(.ant-progress) {
    .ant-progress-text {
      font-size: 12px;
    }
  }

  :deep(.ant-alert) {
    .ant-alert-message {
      font-weight: 500;
    }
  }
</style>
