<script setup lang="ts">
import { onMounted, reactive, ref } from "vue";
import http, { apiError } from "@/api/http";
import PageHeader from "@/components/PageHeader.vue";
import AppIcon from "@/components/AppIcon.vue";
import AdminNumberInput from "@/components/AdminNumberInput.vue";
import { useToastStore } from "@/stores/toast";
const toast = useToastStore(),
  loading = ref(false),
  generating = ref(false),
  dialog = ref(false),
  resultDialog = ref(false),
  items = ref<Record<string, any>[]>([]),
  codes = ref<string[]>([]),
  total = ref(0);
async function copyCode(code: string) {
  await navigator.clipboard.writeText(code);
  toast.success("兑换码已复制");
}
const query = reactive({ keyword: "", status: "", page: 1, page_size: 15 });
const form = reactive({ name: "", points: 10, quantity: 1, expires_at: "" });
async function load() {
  loading.value = true;
  try {
    const { data } = await http.get("/redemption-codes", { params: query });
    items.value = data.data.items;
    total.value = data.data.total;
  } catch (e) {
    show(e);
  } finally {
    loading.value = false;
  }
}
function open() {
  Object.assign(form, { name: "", points: 10, quantity: 1, expires_at: "" });
  dialog.value = true;
}
async function generate() {
  const points = Number(form.points);
  const quantity = Number(form.quantity);
  if (!Number.isFinite(points) || points < 1 || points > 100) {
    toast.warning("单码积分数量必须为 1 至 100");
    return;
  }
  if (!Number.isInteger(quantity) || quantity < 1 || quantity > 10) {
    toast.warning("生成数量必须为 1 至 10");
    return;
  }
  generating.value = true;
  try {
    const { data } = await http.post("/redemption-batches", form);
    codes.value = data.data.codes;
    dialog.value = false;
    resultDialog.value = true;
    toast.success("兑换码批次生成成功");
    load();
  } catch (e) {
    show(e);
  } finally {
    generating.value = false;
  }
}
async function copyAll() {
  await navigator.clipboard.writeText(codes.value.join("\n"));
  toast.success("完整兑换码已复制");
}
function exportCodes() {
  const blob = new Blob([codes.value.join("\r\n")], { type: "text/plain;charset=utf-8" });
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = `redemption-codes-${Date.now()}.txt`;
  a.click();
  URL.revokeObjectURL(url);
}
function closeResult() {
  codes.value = [];
  resultDialog.value = false;
}
function show(e: unknown) {
  const d = apiError(e);
  toast.error(d.message, d.copyText);
}
const statusText = (v: string) => ({ unused: "未使用", used: "已使用", expired: "已过期" })[v] || v;
const fmt = (v: any) =>
  v ? new Date(v).toLocaleString("zh-CN", { timeZone: "Asia/Shanghai", hour12: false }) : "长期有效";
onMounted(load);
</script>
<template>
  <div class="page-stack management-page">
    <PageHeader
      title="兑换码管理"
      description="完整兑换码可在列表中直接查看并复制"
      ><el-button
        type="primary"
        @click="open"
      >
        <AppIcon name="Plus" />生成兑换码
      </el-button></PageHeader
    >
    <section class="panel filter-bar">
      <el-input
        v-model="query.keyword"
        clearable
        placeholder="批次、兑换码或用户 UID"
      /><el-select
        v-model="query.status"
        clearable
        placeholder="状态"
        ><el-option
          label="未使用"
          value="unused" /><el-option
          label="已使用"
          value="used" /><el-option
          label="已过期"
          value="expired" /></el-select
      ><el-button
        type="primary"
        @click="
          query.page = 1;
          load();
        "
        >查询</el-button
      >
    </section>
    <section
      class="panel table-panel"
      v-loading="loading"
    >
      <el-table :data="items"
        ><el-table-column
          prop="code"
          label="兑换码"
          min-width="230"
          show-overflow-tooltip
          ><template #default="{ row }"
            ><span class="code-cell">{{ row.code || "--" }}</span></template
          ></el-table-column
        ><el-table-column
          label="操作"
          width="90"
          fixed="right"
          ><template #default="{ row }"
            ><el-button
              v-if="row.code"
              link
              type="primary"
              @click="copyCode(row.code)"
              ><AppIcon name="CopyDocument" />复制</el-button
            ></template
          ></el-table-column
        ><el-table-column
          prop="batch_name"
          label="所属批次"
          min-width="140" /><el-table-column
          label="积分数量"
          width="110"
          ><template #default="{ row }">{{ Number(row.points).toFixed(2) }}</template></el-table-column
        ><el-table-column
          label="状态"
          width="100"
          ><template #default="{ row }"
            ><el-tag effect="plain">{{ statusText(row.status) }}</el-tag></template
          ></el-table-column
        ><el-table-column
          prop="redeemed_uid"
          label="兑换用户 UID"
          width="130" /><el-table-column
          label="兑换时间"
          min-width="180"
          ><template #default="{ row }">{{ row.redeemed_at ? fmt(row.redeemed_at) : "--" }}</template></el-table-column
        ><el-table-column
          label="失效时间"
          min-width="180"
          ><template #default="{ row }">{{
            row.status === "used" ? "--" : fmt(row.expires_at)
          }}</template></el-table-column
        ><el-table-column
          prop="created_by"
          label="创建管理员"
          width="130" /></el-table
      ><el-empty
        v-if="!loading && !items.length"
        description="暂无兑换码"
      /><el-pagination
        v-if="total > query.page_size"
        v-model:current-page="query.page"
        background
        layout="total,prev,pager,next"
        :total="total"
        @current-change="load"
      />
    </section>
    <el-dialog
      v-model="dialog"
      title="按批次生成兑换码"
      width="min(560px, calc(100vw - 32px))"
      ><el-form
        :model="form"
        label-position="top"
        ><el-form-item
          label="批次名称"
          required
          ><el-input v-model.trim="form.name"
        /></el-form-item>
        <div class="form-grid">
          <el-form-item
            label="单码积分数量"
            required
            ><AdminNumberInput
              v-model="form.points"
              :min="1"
              :max="100"
              :precision="2" /></el-form-item
          ><el-form-item
            label="生成数量"
            required
            ><AdminNumberInput
              v-model="form.quantity"
              :min="1"
              :max="10"
              :precision="0"
          /></el-form-item>
        </div>
        <el-form-item label="有效期"
          ><el-date-picker
            v-model="form.expires_at"
            type="datetime"
            value-format="YYYY-MM-DDTHH:mm:ssZ"
            class="field-full"
        /></el-form-item> </el-form
      ><template #footer
        ><el-button @click="dialog = false">取消</el-button
        ><el-button
          type="primary"
          :loading="generating"
          :disabled="generating"
          @click="generate"
          >生成</el-button
        ></template
      ></el-dialog
    >
    <el-dialog
      :model-value="resultDialog"
      title="完整兑换码（仅展示一次）"
      width="min(720px, calc(100vw - 32px))"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      :show-close="false"
      ><el-alert
        type="warning"
        :closable="false"
        title="关闭后系统无法再次查看完整兑换码，请立即复制或导出。"
      /><el-input
        class="code-output"
        :model-value="codes.join('\n')"
        type="textarea"
        :rows="12"
        readonly
      /><template #footer
        ><el-button @click="copyAll"> <AppIcon name="CopyDocument" />复制全部 </el-button
        ><el-button @click="exportCodes"> <AppIcon name="Download" />导出文件 </el-button
        ><el-button
          type="primary"
          @click="closeResult"
          >我已保存，关闭</el-button
        ></template
      ></el-dialog
    >
  </div>
</template>
