"use client";

import {
  useCreate,
  useGetIdentity,
  useInvalidate,
  useUpdate,
} from "@refinedev/core";
import {
  App,
  Button,
  DatePicker,
  Form,
  Input,
  InputNumber,
  Modal,
  Space,
  Tag,
  Typography,
  type TableColumnsType,
} from "antd";
import dayjs from "dayjs";
import { useState } from "react";

import { ConfirmActionModal } from "@/components/admin/confirm-action-modal";
import {
  formatAdminDate,
  ResourceTable,
} from "@/components/admin/resource-table";
import { adminRequestJson, type AdminIdentity } from "@/lib/admin/providers";

type CodeRecord = {
  id: string;
  code?: string;
  mask: string;
  credits: number;
  expiresAt: string | null;
  note: string | null;
  createdAt: string;
  redeemedEmail: string | null;
  redeemedAt: string | null;
  revokedAt: string | null;
  status: "available" | "expired" | "redeemed" | "revoked";
};

type CreateValues = {
  credits: number;
  count: number;
  expiresAt?: ReturnType<typeof dayjs>;
  note?: string;
};
type EditValues = {
  note?: string;
  expiresAt?: ReturnType<typeof dayjs> | null;
};

const statusColors: Record<CodeRecord["status"], string> = {
  available: "green",
  expired: "orange",
  redeemed: "blue",
  revoked: "red",
};

export default function CodesPage() {
  const { message } = App.useApp();
  const invalidate = useInvalidate();
  const { data: identity } = useGetIdentity<AdminIdentity>();
  const { mutateAsync: createCodes, mutation: createMutation } = useCreate<{
    id: string;
    generated: CodeRecord[];
  }>();
  const { mutateAsync: updateCode, mutation: updateMutation } =
    useUpdate<CodeRecord>();
  const [createOpen, setCreateOpen] = useState(false);
  const [pendingCreate, setPendingCreate] = useState<CreateValues | null>(null);
  const [editRecord, setEditRecord] = useState<CodeRecord | null>(null);
  const [pendingEdit, setPendingEdit] = useState<EditValues | null>(null);
  const [generated, setGenerated] = useState<CodeRecord[]>([]);
  const [revokeRecord, setRevokeRecord] = useState<CodeRecord | null>(null);
  const [revoking, setRevoking] = useState(false);
  const [createForm] = Form.useForm<CreateValues>();
  const [editForm] = Form.useForm<EditValues>();
  const writable = Boolean(
    identity?.permissions.includes("billing.adjustments.write"),
  );

  async function submitCreate() {
    if (!pendingCreate) return;
    const result = await createCodes({
      resource: "codes",
      values: {
        credits: pendingCreate.credits,
        count: pendingCreate.count,
        expiresAt: pendingCreate.expiresAt?.toISOString() ?? null,
        note: pendingCreate.note?.trim() || null,
      },
      successNotification: false,
    });
    setGenerated(result.data.generated);
    setPendingCreate(null);
    setCreateOpen(false);
    createForm.resetFields();
  }

  async function submitEdit() {
    if (!editRecord || !pendingEdit) return;
    await updateCode({
      resource: "codes",
      id: editRecord.id,
      values: {
        note: pendingEdit.note?.trim() || null,
        expiresAt: pendingEdit.expiresAt?.toISOString() ?? null,
      },
    });
    setPendingEdit(null);
    setEditRecord(null);
  }

  async function revoke(record: CodeRecord) {
    setRevoking(true);
    try {
      await adminRequestJson(`/api/admin/codes/${record.id}`, {
        method: "DELETE",
        headers: { "x-request-id": crypto.randomUUID() },
      });
      await invalidate({ resource: "codes", invalidates: ["list"] });
      message.success("兑换码已撤销");
      setRevokeRecord(null);
    } catch (error) {
      message.error(error instanceof Error ? error.message : "撤销失败");
    } finally {
      setRevoking(false);
    }
  }

  const columns: TableColumnsType<CodeRecord> = [
    { title: "兑换码", dataIndex: "mask" },
    { title: "点数", dataIndex: "credits", sorter: true },
    {
      title: "状态",
      dataIndex: "status",
      sorter: true,
      render: (value) => (
        <Tag color={statusColors[value as CodeRecord["status"]]}>{value}</Tag>
      ),
    },
    {
      title: "到期时间",
      dataIndex: "expiresAt",
      sorter: true,
      render: formatAdminDate,
    },
    { title: "备注", dataIndex: "note", render: (value) => value || "—" },
    {
      title: "兑换账户",
      dataIndex: "redeemedEmail",
      render: (value) => value || "—",
    },
    { title: "兑换时间", dataIndex: "redeemedAt", render: formatAdminDate },
    { title: "撤销时间", dataIndex: "revokedAt", render: formatAdminDate },
    {
      title: "创建时间",
      dataIndex: "createdAt",
      sorter: true,
      render: formatAdminDate,
    },
    {
      title: "操作",
      fixed: "right",
      render: (_, record) =>
        writable &&
        record.status !== "redeemed" &&
        record.status !== "revoked" ? (
          <Space>
            <Button
              size="small"
              onClick={() => {
                setPendingEdit(null);
                setEditRecord(record);
                editForm.setFieldsValue({
                  note: record.note ?? undefined,
                  expiresAt: record.expiresAt ? dayjs(record.expiresAt) : null,
                });
              }}
            >
              编辑
            </Button>
            <Button
              danger
              size="small"
              loading={revoking && revokeRecord?.id === record.id}
              onClick={() => setRevokeRecord(record)}
            >
              撤销
            </Button>
          </Space>
        ) : (
          "—"
        ),
    },
  ];

  return (
    <>
      <ResourceTable<CodeRecord>
        resource="codes"
        title={`兑换码${identity ? ` · ${identity.email} (${identity.roles.join("、")})` : ""}`}
        columns={columns}
        statusOptions={[
          { label: "可用", value: "available" },
          { label: "已过期", value: "expired" },
          { label: "已兑换", value: "redeemed" },
          { label: "已撤销", value: "revoked" },
        ]}
        extra={
          writable ? (
            <Button
              type="primary"
              onClick={() => {
                setPendingCreate(null);
                setCreateOpen(true);
              }}
            >
              批量生成
            </Button>
          ) : null
        }
      />

      <Modal
        title="批量生成兑换码"
        open={createOpen}
        onCancel={() => {
          setPendingCreate(null);
          setCreateOpen(false);
        }}
        footer={null}
        destroyOnHidden
      >
        <Form
          form={createForm}
          layout="vertical"
          initialValues={{ credits: 10, count: 1 }}
          onFinish={setPendingCreate}
        >
          <Form.Item
            name="credits"
            label="每个点数"
            rules={[{ required: true }]}
          >
            <InputNumber min={1} max={1_000_000} style={{ width: "100%" }} />
          </Form.Item>
          <Form.Item name="count" label="数量" rules={[{ required: true }]}>
            <InputNumber min={1} max={100} style={{ width: "100%" }} />
          </Form.Item>
          <Form.Item name="expiresAt" label="到期时间">
            <DatePicker showTime style={{ width: "100%" }} />
          </Form.Item>
          <Form.Item name="note" label="备注">
            <Input maxLength={500} />
          </Form.Item>
          <Button
            block
            type="primary"
            htmlType="submit"
            loading={createMutation.isPending}
          >
            生成
          </Button>
        </Form>
      </Modal>

      <Modal
        title="完整兑换码（仅显示本次）"
        open={generated.length > 0}
        onCancel={() => setGenerated([])}
        footer={<Button onClick={() => setGenerated([])}>我已保存</Button>}
      >
        <Typography.Paragraph type="warning">
          关闭后无法再次查看完整兑换码，请立即安全保存。
        </Typography.Paragraph>
        {generated.map((record) => (
          <Typography.Paragraph copyable key={record.code}>
            <Typography.Text code>{record.code}</Typography.Text>
          </Typography.Paragraph>
        ))}
      </Modal>

      <Modal
        title="编辑未兑换码"
        open={Boolean(editRecord)}
        onCancel={() => {
          setPendingEdit(null);
          setEditRecord(null);
        }}
        footer={null}
        destroyOnHidden
      >
        <Form form={editForm} layout="vertical" onFinish={setPendingEdit}>
          <Form.Item name="expiresAt" label="到期时间">
            <DatePicker showTime style={{ width: "100%" }} />
          </Form.Item>
          <Form.Item name="note" label="备注">
            <Input maxLength={500} />
          </Form.Item>
          <Button
            block
            type="primary"
            htmlType="submit"
            loading={updateMutation.isPending}
          >
            保存
          </Button>
        </Form>
      </Modal>
      <ConfirmActionModal
        open={Boolean(pendingCreate)}
        title="生成兑换码"
        okText="确认生成"
        confirmLoading={createMutation.isPending}
        onCancel={() => setPendingCreate(null)}
        onConfirm={submitCreate}
      />
      <ConfirmActionModal
        open={Boolean(pendingEdit)}
        title="编辑未兑换码"
        okText="确认保存"
        confirmLoading={updateMutation.isPending}
        onCancel={() => setPendingEdit(null)}
        onConfirm={submitEdit}
      />
      <ConfirmActionModal
        open={Boolean(revokeRecord)}
        title="撤销兑换码"
        okText="确认撤销"
        danger
        confirmLoading={revoking}
        onCancel={() => setRevokeRecord(null)}
        onConfirm={() => revoke(revokeRecord!)}
      />
    </>
  );
}
