/**
 * 积分系统 API 模块
 * ==================
 *
 * 提供积分余额查询、充值下单、支付状态查询等功能。
 */

import { client } from '../client';

// ── 类型定义 ──────────────────────────────────────────

export interface PointBalance {
  balance: number;
  totalRecharged: number;
  totalConsumed: number;
  totalExpired: number;
}

export interface RechargeOption {
  price: number; // 人民币（分）
  points: number; // 到账积分数
  label: string; // 标签，空字符串不显示
  validityDays: number; // 积分有效期（天），0 表示永久有效
}

export interface RechargeOrder {
  orderId: number;
  points: number;
  amountRmb: number;
  codeUrl: string | null;
  expireAt: string | null; // ISO 格式，二维码过期时间
}

interface RechargeOrderStatus {
  orderId: number;
  status: 'pending' | 'paid' | 'failed' | 'closed';
  points: number;
  amountRmb: number;
  paidAt: string | null;
  wxOrderNo: string | null;
}

export interface PointTransaction {
  id: number;
  type: 'recharge' | 'consume' | 'expire' | 'refund';
  amount: number;
  balanceBefore: number;
  balanceAfter: number;
  sourceType: string | null;
  sourceId: string | null;
  duration: number | null;
  description: string | null;
  createdAt: string;
}

interface PointTransactionList {
  items: PointTransaction[];
  total: number;
  skip: number;
  limit: number;
}

// ── API 方法 ──────────────────────────────────────────

export interface PointRule {
  sourceType: string;
  mode: 'fixed' | 'duration' | 'free';
  points?: number;
  minPoints?: number;
  unit?: string;
  pointsPerUnit?: number;
}

export const pointsApi = {
  /**
   * 获取积分计费规则列表
   * GET /points/rules
   */
  getRules: async (): Promise<PointRule[]> => {
    return client.get<PointRule[]>('/points/rules');
  },

  /**
   * 获取当前用户积分余额
   * GET /points/balance
   */
  getBalance: async (): Promise<PointBalance> => {
    return client.get<PointBalance>('/points/balance');
  },

  /**
   * 创建充值订单（微信支付 Native 扫码）
   * POST /points/recharge
   */
  /**
   * 获取充值档位配置（由后端控制）
   * GET /points/recharge-options
   */
  getRechargeOptions: async (): Promise<RechargeOption[]> => {
    return client.get<RechargeOption[]>('/points/recharge-options');
  },

  /**
   * 获取所有需要扣费的业务类型列表
   * GET /points/chargeable-types
   *
   * 用于积分明细页面的类型筛选，只展示会产生积分消耗的业务。
   */
  getChargeableTypes: async (): Promise<string[]> => {
    return client.get<string[]>('/points/chargeable-types');
  },

  /**
   * 创建充值订单（微信支付 Native 扫码）
   * POST /points/recharge
   */
  createRechargeOrder: async (
    points: number,
    amountRmb: number,
  ): Promise<RechargeOrder> => {
    return client.post<RechargeOrder>('/points/recharge', {
      points,
      amount_rmb: amountRmb,
    });
  },

  /**
   * 查询充值订单支付状态
   * GET /points/recharge/query/{orderId}
   */
  queryRechargeStatus: async (
    orderId: number,
  ): Promise<RechargeOrderStatus> => {
    return client.get<RechargeOrderStatus>(`/points/recharge/query/${orderId}`);
  },

  /**
   * 获取积分流水记录（支持筛选）
   * GET /points/transactions
   */
  getTransactions: async (params: {
    page?: number;
    pageSize?: number;
    txType?: 'consume' | 'recharge' | 'expire';
    sourceType?: string;
    startTime?: string;
    endTime?: string;
  } = {}): Promise<PointTransactionList> => {
    const {
      page = 1,
      pageSize = 20,
      txType,
      sourceType,
      startTime,
      endTime,
    } = params;
    const query = new URLSearchParams();
    query.set('page', String(page));
    query.set('page_size', String(pageSize));
    if (txType) {query.set('tx_type', txType);}
    if (sourceType) {query.set('source_type', sourceType);}
    if (startTime) {query.set('start_time', startTime);}
    if (endTime) {query.set('end_time', endTime);}
    return client.get<PointTransactionList>(
      `/points/transactions?${query.toString()}`,
    );
  },

  /**
   * GET /points/today-consumed
   *
   * 获取今日消费积分总额。
   */
  getTodayConsumed: async (): Promise<{ total: number }> => {
    return client.get<{ total: number }>('/points/today-consumed');
  },

  /**
   * 直接消费积分（前端/Rust 层业务扣费）
   * POST /points/consume
   *
   * 余额不足时后端返回 402，调用方应捕获并引导充值。
   */
  consumePoints: async (payload: {
    points: number;
    sourceType: string;
    sourceId: string;
    description?: string;
    allowNegative?: boolean;
  }): Promise<{
    transactionId: number;
    consumedPoints: number;
    balanceAfter: number;
    sourceType: string;
  }> => {
    return client.post('/points/consume', {
      points: payload.points,
      source_type: payload.sourceType,
      source_id: payload.sourceId,
      description: payload.description,
      allow_negative: payload.allowNegative ?? false,
    });
  },
};
