<script setup lang="ts">
import { Delete, Edit, Plus, Refresh, Search, Tickets, View } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from 'element-plus'
import {
  createCouponApi,
  deleteCouponApi,
  getCouponPageApi,
  getCouponRecordsApi,
  updateCouponApi,
  updateCouponStatusApi
} from '@/api/coupon'
import type {
  CouponItem,
  CouponPageQuery,
  CouponSavePayload,
  CouponStatus,
  CouponType,
  UserCouponRecord,
  UserCouponStatus
} from '@/api/coupon'
import { formatDate } from '@/utils/date'
import SearchBar from '@/components/common/SearchBar.vue'

const typeOptions: Array<{ label: string; value: CouponType; tag: 'danger' | 'warning' | 'success' }> = [
  { label: '满减券', value: 0, tag: 'danger' },
  { label: '折扣券', value: 1, tag: 'warning' },
  { label: '无门槛券', value: 2, tag: 'success' }
]

const statusOptions: Array<{ label: string; value: CouponStatus; tag: 'info' | 'success' | 'warning' }> = [
  { label: '未上线', value: 0, tag: 'info' },
  { label: '已上线', value: 1, tag: 'success' },
  { label: '已结束', value: 2, tag: 'warning' }
]

const recordStatusOptions: Array<{ label: string; value: UserCouponStatus; tag: 'success' | 'primary' | 'warning' | 'info' }> = [
  { label: '未使用', value: 0, tag: 'success' },
  { label: '已使用', value: 1, tag: 'primary' },
  { label: '已过期', value: 2, tag: 'warning' },
  { label: '已作废', value: 3, tag: 'info' }
]

const loading = ref(false)
const list = ref<CouponItem[]>([])
const total = ref(0)

const query = reactive<CouponPageQuery>({
  current: 1,
  size: 10,
  keyword: '',
  type: undefined,
  status: undefined
})

const dialogVisible = ref(false)
const dialogMode = ref<'add' | 'edit'>('add')
const submitting = ref(false)
const formRef = ref<FormInstance>()
const form = reactive<CouponSavePayload>({
  name: '',
  type: 0,
  amount: 10,
  minAmount: 99,
  maxDiscount: 0,
  total: 100,
  perLimit: 1,
  status: 1,
  startTime: '',
  endTime: '',
  validDays: 30,
  description: ''
})

const rules: FormRules = {
  name: [{ required: true, message: '请输入优惠券名称', trigger: 'blur' }],
  type: [{ required: true, message: '请选择优惠券类型', trigger: 'change' }],
  amount: [{ required: true, message: '请输入优惠金额或折扣率', trigger: 'blur' }],
  total: [{ required: true, message: '请输入发放总量', trigger: 'blur' }],
  perLimit: [{ required: true, message: '请输入每人限领数量', trigger: 'blur' }],
  startTime: [{ required: true, message: '请选择开始时间', trigger: 'change' }],
  endTime: [{ required: true, message: '请选择截止时间', trigger: 'change' }]
}

const recordDrawerVisible = ref(false)
const recordLoading = ref(false)
const activeCoupon = ref<CouponItem | null>(null)
const recordList = ref<UserCouponRecord[]>([])
const recordTotal = ref(0)
const recordQuery = reactive({
  current: 1,
  size: 10,
  keyword: '',
  status: undefined as UserCouponStatus | undefined
})

const dialogTitle = computed(() => (dialogMode.value === 'add' ? '创建优惠券' : '编辑优惠券'))

function typeMeta(type: CouponType) {
  return typeOptions.find((item) => item.value === type) ?? typeOptions[0]
}

function statusMeta(status: CouponStatus) {
  return statusOptions.find((item) => item.value === status) ?? statusOptions[0]
}

function recordStatusMeta(status: UserCouponStatus) {
  return recordStatusOptions.find((item) => item.value === status) ?? recordStatusOptions[0]
}

function asCoupon(row: unknown): CouponItem {
  return row as CouponItem
}

function asRecord(row: unknown): UserCouponRecord {
  return row as UserCouponRecord
}

function formatDiscount(row: CouponItem | CouponSavePayload | unknown) {
  const item = row as CouponItem | CouponSavePayload
  if (item.type === 1) {
    return `${(Number(item.amount) * 10).toFixed(1)} 折`
  }
  return `¥ ${Number(item.amount).toFixed(2)}`
}

function stockText(row: unknown) {
  const item = asCoupon(row)
  if (item.total === -1) return '不限量'
  return `${item.total - item.remain} / ${item.total}`
}

async function fetchData() {
  loading.value = true
  try {
    const res = await getCouponPageApi(query)
    list.value = res.records
    total.value = res.total
  } finally {
    loading.value = false
  }
}

function handleSearch() {
  query.current = 1
  fetchData()
}

function resetQuery() {
  query.current = 1
  query.keyword = ''
  query.type = undefined
  query.status = undefined
  fetchData()
}

function resetForm() {
  Object.assign(form, {
    id: undefined,
    name: '',
    type: 0,
    amount: 10,
    minAmount: 99,
    maxDiscount: 0,
    total: 100,
    perLimit: 1,
    status: 1,
    startTime: '',
    endTime: '',
    validDays: 30,
    description: ''
  })
}

function openAdd() {
  dialogMode.value = 'add'
  resetForm()
  dialogVisible.value = true
}

function openEdit(row: unknown) {
  const item = asCoupon(row)
  dialogMode.value = 'edit'
  Object.assign(form, {
    id: item.id,
    name: item.name,
    type: item.type,
    amount: item.amount,
    minAmount: item.minAmount,
    maxDiscount: item.maxDiscount,
    total: item.total,
    perLimit: item.perLimit,
    status: item.status,
    startTime: item.startTime?.replace(' ', 'T'),
    endTime: item.endTime?.replace(' ', 'T'),
    validDays: item.validDays ?? null,
    description: item.description ?? ''
  })
  dialogVisible.value = true
}

async function handleSubmit() {
  const valid = await formRef.value?.validate().catch(() => false)
  if (!valid) return
  if (form.type === 1 && Number(form.amount) >= 1) {
    ElMessage.warning('折扣券折扣率需小于 1，例如 0.90 表示 9 折')
    return
  }
  if (form.type === 2) {
    form.minAmount = 0
  }

  submitting.value = true
  try {
    if (dialogMode.value === 'add') {
      await createCouponApi(form)
      ElMessage.success('创建成功')
    } else {
      await updateCouponApi(form)
      ElMessage.success('更新成功')
    }
    dialogVisible.value = false
    fetchData()
  } finally {
    submitting.value = false
  }
}

async function handleDelete(row: unknown) {
  const item = asCoupon(row)
  await ElMessageBox.confirm(`确定删除优惠券「${item.name}」吗？已有领取记录的优惠券不能删除。`, '删除确认', {
    type: 'warning'
  })
  await deleteCouponApi(item.id)
  ElMessage.success('删除成功')
  fetchData()
}

async function handleStatus(row: unknown, status: CouponStatus) {
  const item = asCoupon(row)
  await updateCouponStatusApi(item.id, status)
  ElMessage.success('状态已更新')
  fetchData()
}

async function openRecords(row: unknown) {
  const item = asCoupon(row)
  activeCoupon.value = item
  recordDrawerVisible.value = true
  recordQuery.current = 1
  recordQuery.keyword = ''
  recordQuery.status = undefined
  await fetchRecords()
}

async function fetchRecords() {
  if (!activeCoupon.value) return
  recordLoading.value = true
  try {
    const res = await getCouponRecordsApi(activeCoupon.value.id, recordQuery)
    recordList.value = res.records
    recordTotal.value = res.total
  } finally {
    recordLoading.value = false
  }
}

function handleRecordSearch() {
  recordQuery.current = 1
  fetchRecords()
}

fetchData()
</script>

<template>
  <div class="page-container coupon-page">
    <div class="page-header">
      <div>
        <h2>优惠券管理</h2>
        <p class="page-desc">配置优惠券模板，查看用户领取与使用情况</p>
      </div>
      <el-button type="primary" :icon="Plus" @click="openAdd">创建优惠券</el-button>
    </div>

    <el-card shadow="never" class="table-card">
      <SearchBar show-divider>
        <div class="toolbar">
          <el-input
            v-model="query.keyword"
            clearable
            class="toolbar-item keyword"
            placeholder="搜索优惠券名称"
            :prefix-icon="Search"
            @keyup.enter="handleSearch"
          />
          <el-select v-model="query.type" clearable class="toolbar-item" placeholder="券类型">
            <el-option v-for="item in typeOptions" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
          <el-select v-model="query.status" clearable class="toolbar-item" placeholder="状态">
            <el-option v-for="item in statusOptions" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
          <el-button type="primary" :icon="Search" @click="handleSearch">查询</el-button>
          <el-button :icon="Refresh" @click="resetQuery">重置</el-button>
        </div>
      </SearchBar>

      <el-table v-loading="loading" :data="list" stripe>
        <el-table-column prop="id" label="ID" width="80" align="center" />
        <el-table-column prop="name" label="优惠券名称" min-width="180" show-overflow-tooltip />
        <el-table-column label="类型" width="110" align="center">
          <template #default="{ row }">
            <el-tag :type="typeMeta(asCoupon(row).type).tag" size="small">
              {{ typeMeta(asCoupon(row).type).label }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="优惠" width="120" align="center">
          <template #default="{ row }">
            <span class="amount">{{ formatDiscount(row) }}</span>
          </template>
        </el-table-column>
        <el-table-column label="门槛" width="120" align="center">
          <template #default="{ row }">
            <span v-if="asCoupon(row).minAmount > 0">满 ¥ {{ asCoupon(row).minAmount }}</span>
            <span v-else class="text-muted">无门槛</span>
          </template>
        </el-table-column>
        <el-table-column label="库存" width="130" align="center">
          <template #default="{ row }">
            <span>{{ stockText(row) }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="perLimit" label="限领" width="90" align="center" />
        <el-table-column label="状态" width="100" align="center">
          <template #default="{ row }">
            <el-tag :type="statusMeta(asCoupon(row).status).tag" size="small">
              {{ statusMeta(asCoupon(row).status).label }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="领取时间" min-width="260">
          <template #default="{ row }">
            <span class="time-cell">
              {{ formatDate(asCoupon(row).startTime, 'MM-DD HH:mm') }} -
              {{ formatDate(asCoupon(row).endTime, 'MM-DD HH:mm') }}
            </span>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="300" fixed="right" align="center">
          <template #default="{ row }">
            <el-button link type="primary" size="small" :icon="Edit" @click="openEdit(row)">编辑</el-button>
            <el-button link type="primary" size="small" :icon="Tickets" @click="openRecords(row)">记录</el-button>
            <el-button
              v-if="asCoupon(row).status !== 1"
              link
              type="success"
              size="small"
              @click="handleStatus(row, 1)"
            >
              上线
            </el-button>
            <el-button
              v-if="asCoupon(row).status === 1"
              link
              type="warning"
              size="small"
              @click="handleStatus(row, 0)"
            >
              下线
            </el-button>
            <el-button
              v-if="asCoupon(row).status !== 2"
              link
              type="info"
              size="small"
              @click="handleStatus(row, 2)"
            >
              结束
            </el-button>
            <el-button link type="danger" size="small" :icon="Delete" @click="handleDelete(row)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>

      <div class="pagination-wrapper">
        <el-pagination
          v-model:current-page="query.current"
          v-model:page-size="query.size"
          :page-sizes="[10, 20, 50]"
          :total="total"
          layout="total, sizes, prev, pager, next"
          background
          @size-change="handleSearch"
          @current-change="fetchData"
        />
      </div>
    </el-card>

    <el-dialog v-model="dialogVisible" :title="dialogTitle" width="680px" destroy-on-close>
      <el-form ref="formRef" :model="form" :rules="rules" label-width="112px">
        <el-form-item label="优惠券名称" prop="name">
          <el-input v-model="form.name" maxlength="100" show-word-limit placeholder="例如：满 99 减 10" />
        </el-form-item>
        <el-form-item label="优惠券类型" prop="type">
          <el-radio-group v-model="form.type">
            <el-radio-button v-for="item in typeOptions" :key="item.value" :value="item.value">
              {{ item.label }}
            </el-radio-button>
          </el-radio-group>
        </el-form-item>
        <el-form-item :label="form.type === 1 ? '折扣率' : '优惠金额'" prop="amount">
          <el-input-number
            v-model="form.amount"
            :min="0.01"
            :max="form.type === 1 ? 0.99 : 99999"
            :step="form.type === 1 ? 0.01 : 1"
            :precision="form.type === 1 ? 2 : 2"
          />
          <span class="form-tip">{{ form.type === 1 ? '0.90 表示 9 折' : '单位：元' }}</span>
        </el-form-item>
        <el-form-item v-if="form.type !== 2" label="使用门槛">
          <el-input-number v-model="form.minAmount" :min="0" :step="10" :precision="2" />
          <span class="form-tip">订单金额满该值可用</span>
        </el-form-item>
        <el-form-item v-if="form.type === 1" label="最高抵扣">
          <el-input-number v-model="form.maxDiscount" :min="0" :step="10" :precision="2" />
          <span class="form-tip">0 表示不限制</span>
        </el-form-item>
        <el-form-item label="发放总量" prop="total">
          <el-input-number v-model="form.total" :min="-1" :step="100" />
          <span class="form-tip">填 -1 表示不限量</span>
        </el-form-item>
        <el-form-item label="每人限领" prop="perLimit">
          <el-input-number v-model="form.perLimit" :min="1" />
        </el-form-item>
        <el-form-item label="状态">
          <el-select v-model="form.status" class="form-select">
            <el-option v-for="item in statusOptions" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
        </el-form-item>
        <el-form-item label="领取时间" required>
          <div class="date-range">
            <el-form-item prop="startTime">
              <el-date-picker
                v-model="form.startTime"
                type="datetime"
                value-format="YYYY-MM-DDTHH:mm:ss"
                placeholder="开始时间"
              />
            </el-form-item>
            <span class="range-separator">至</span>
            <el-form-item prop="endTime">
              <el-date-picker
                v-model="form.endTime"
                type="datetime"
                value-format="YYYY-MM-DDTHH:mm:ss"
                placeholder="截止时间"
              />
            </el-form-item>
          </div>
        </el-form-item>
        <el-form-item label="领取后有效">
          <el-input-number v-model="form.validDays" :min="1" :max="3650" />
          <span class="form-tip">为空时按领取截止时间过期</span>
        </el-form-item>
        <el-form-item label="使用说明">
          <el-input
            v-model="form.description"
            type="textarea"
            maxlength="500"
            show-word-limit
            :rows="3"
            placeholder="例如：仅限普通商品使用，不与其他活动同享"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" :loading="submitting" @click="handleSubmit">保存</el-button>
      </template>
    </el-dialog>

    <el-drawer
      v-model="recordDrawerVisible"
      :title="activeCoupon ? `领取记录：${activeCoupon.name}` : '领取记录'"
      size="760px"
    >
      <div class="record-toolbar">
        <el-input
          v-model="recordQuery.keyword"
          clearable
          class="record-keyword"
          placeholder="搜索用户名/昵称/手机号"
          :prefix-icon="Search"
          @keyup.enter="handleRecordSearch"
        />
        <el-select v-model="recordQuery.status" clearable class="record-status" placeholder="使用状态">
          <el-option
            v-for="item in recordStatusOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select>
        <el-button type="primary" :icon="View" @click="handleRecordSearch">查看</el-button>
      </div>

      <el-table v-loading="recordLoading" :data="recordList" stripe>
        <el-table-column prop="id" label="ID" width="76" align="center" />
        <el-table-column label="用户" min-width="150">
          <template #default="{ row }">
            <div class="user-cell">
              <span>{{ asRecord(row).nickname || asRecord(row).username || '-' }}</span>
              <small>{{ asRecord(row).username || `ID: ${asRecord(row).userId}` }}</small>
            </div>
          </template>
        </el-table-column>
        <el-table-column label="状态" width="100" align="center">
          <template #default="{ row }">
            <el-tag :type="recordStatusMeta(asRecord(row).status).tag" size="small">
              {{ recordStatusMeta(asRecord(row).status).label }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="领取时间" min-width="150">
          <template #default="{ row }">{{ formatDate(asRecord(row).receiveTime, 'MM-DD HH:mm') }}</template>
        </el-table-column>
        <el-table-column label="过期时间" min-width="150">
          <template #default="{ row }">{{ formatDate(asRecord(row).expireTime, 'MM-DD HH:mm') }}</template>
        </el-table-column>
        <el-table-column label="订单" width="110" align="center">
          <template #default="{ row }">{{ asRecord(row).orderId || '-' }}</template>
        </el-table-column>
      </el-table>

      <div class="pagination-wrapper">
        <el-pagination
          v-model:current-page="recordQuery.current"
          v-model:page-size="recordQuery.size"
          :total="recordTotal"
          layout="total, prev, pager, next"
          background
          @current-change="fetchRecords"
        />
      </div>
    </el-drawer>
  </div>
</template>

<style lang="scss" scoped>
.toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
}

.toolbar-item {
  width: 160px;
}

.keyword {
  width: 240px;
}

.amount {
  color: $color-danger;
  font-weight: 600;
}

.text-muted,
.form-tip {
  color: $color-text-placeholder;
  font-size: 12px;
}

.form-tip {
  margin-left: 10px;
}

.time-cell {
  color: $color-text-secondary;
  font-size: 12px;
}

.form-select {
  width: 180px;
}

.date-range {
  display: flex;
  align-items: flex-start;
  gap: 8px;
}

.range-separator {
  color: $color-text-secondary;
  line-height: 32px;
}

.record-toolbar {
  display: flex;
  gap: 12px;
  margin-bottom: 16px;
}

.record-keyword {
  width: 260px;
}

.record-status {
  width: 140px;
}

.user-cell {
  display: flex;
  flex-direction: column;
  gap: 2px;

  small {
    color: $color-text-placeholder;
  }
}

.pagination-wrapper {
  display: flex;
  justify-content: flex-end;
  padding: 16px 20px;
}
</style>
