import { apiRequest } from "@/shared/api/request"; import { API_ENDPOINTS, API_OPERATIONS, apiEndpointPath } from "@/shared/api/generated/endpoints"; import type { ApiPage, PageQuery } from "@/shared/api/types"; export interface InviteActivityRewardTierDto { tierId: number; rewardType: string; tierCode: string; tierName: string; thresholdCoinAmount: number; thresholdValidInviteCount: number; rewardCoinAmount: number; status: string; sortOrder: number; createdAtMs?: number; updatedAtMs?: number; } export interface InviteActivityRewardConfigDto { appCode?: string; enabled: boolean; perInviteInviterRewardCoinAmount: number; perInviteInviteeRewardCoinAmount: number; tiers: InviteActivityRewardTierDto[]; updatedByAdminId?: number; createdAtMs?: number; updatedAtMs?: number; } export interface InviteActivityRewardConfigPayload { enabled: boolean; per_invite_inviter_reward_coin_amount: number; per_invite_invitee_reward_coin_amount: number; tiers: Array<{ tier_id?: number; reward_type: string; tier_code: string; tier_name: string; threshold_coin_amount: number; threshold_valid_invite_count: number; reward_coin_amount: number; status: string; sort_order: number; }>; } export interface InviteActivityRewardClaimUserDto { userId?: number; displayUserId?: string; username?: string; avatar?: string; } export interface InviteActivityRewardClaimDto { claimId: string; appCode?: string; cycleKey?: string; userId: number; user?: InviteActivityRewardClaimUserDto; rewardType?: string; commandId?: string; tierId?: number; tierCode?: string; tierName?: string; thresholdCoinAmount?: number; thresholdValidInviteCount?: number; reachedValue?: number; rewardCoinAmount?: number; status?: string; walletCommandId?: string; walletTransactionId?: string; failureReason?: string; grantedAtMs?: number; createdAtMs?: number; updatedAtMs?: number; } type RawConfig = InviteActivityRewardConfigDto & Record; type RawTier = InviteActivityRewardTierDto & Record; type RawClaim = InviteActivityRewardClaimDto & Record; export function getInviteActivityRewardConfig(): Promise { const endpoint = API_ENDPOINTS.getInviteActivityRewardConfig; return apiRequest(apiEndpointPath(API_OPERATIONS.getInviteActivityRewardConfig), { method: endpoint.method, }).then(normalizeConfig); } export function updateInviteActivityRewardConfig( payload: InviteActivityRewardConfigPayload, ): Promise { const endpoint = API_ENDPOINTS.updateInviteActivityRewardConfig; return apiRequest( apiEndpointPath(API_OPERATIONS.updateInviteActivityRewardConfig), { body: payload, method: endpoint.method, }, ).then(normalizeConfig); } export function listInviteActivityRewardClaims(query: PageQuery = {}): Promise> { const endpoint = API_ENDPOINTS.listInviteActivityRewardClaims; return apiRequest>(apiEndpointPath(API_OPERATIONS.listInviteActivityRewardClaims), { method: endpoint.method, query, }).then((page) => ({ ...page, items: (page.items || []).map(normalizeClaim), })); } function normalizeConfig(item: RawConfig): InviteActivityRewardConfigDto { const rawTiers = Array.isArray(item.tiers) ? (item.tiers as RawTier[]) : []; return { appCode: stringValue(item.appCode ?? item.app_code), enabled: Boolean(item.enabled), perInviteInviterRewardCoinAmount: numberValue( item.perInviteInviterRewardCoinAmount ?? item.per_invite_inviter_reward_coin_amount, ), perInviteInviteeRewardCoinAmount: numberValue( item.perInviteInviteeRewardCoinAmount ?? item.per_invite_invitee_reward_coin_amount, ), tiers: rawTiers.map(normalizeTier), updatedByAdminId: numberValue(item.updatedByAdminId ?? item.updated_by_admin_id), createdAtMs: numberValue(item.createdAtMs ?? item.created_at_ms), updatedAtMs: numberValue(item.updatedAtMs ?? item.updated_at_ms), }; } function normalizeTier(item: RawTier): InviteActivityRewardTierDto { return { tierId: numberValue(item.tierId ?? item.tier_id), rewardType: stringValue(item.rewardType ?? item.reward_type), tierCode: stringValue(item.tierCode ?? item.tier_code), tierName: stringValue(item.tierName ?? item.tier_name), thresholdCoinAmount: numberValue(item.thresholdCoinAmount ?? item.threshold_coin_amount), thresholdValidInviteCount: numberValue(item.thresholdValidInviteCount ?? item.threshold_valid_invite_count), rewardCoinAmount: numberValue(item.rewardCoinAmount ?? item.reward_coin_amount), status: stringValue(item.status) || "active", sortOrder: numberValue(item.sortOrder ?? item.sort_order), createdAtMs: numberValue(item.createdAtMs ?? item.created_at_ms), updatedAtMs: numberValue(item.updatedAtMs ?? item.updated_at_ms), }; } function normalizeClaim(item: RawClaim): InviteActivityRewardClaimDto { const rawUser = (item.user || {}) as Record; return { claimId: stringValue(item.claimId ?? item.claim_id), appCode: stringValue(item.appCode ?? item.app_code), cycleKey: stringValue(item.cycleKey ?? item.cycle_key), userId: numberValue(item.userId ?? item.user_id), user: { userId: numberValue(rawUser.userId ?? rawUser.user_id), displayUserId: stringValue(rawUser.displayUserId ?? rawUser.display_user_id), username: stringValue(rawUser.username), avatar: stringValue(rawUser.avatar), }, rewardType: stringValue(item.rewardType ?? item.reward_type), commandId: stringValue(item.commandId ?? item.command_id), tierId: numberValue(item.tierId ?? item.tier_id), tierCode: stringValue(item.tierCode ?? item.tier_code), tierName: stringValue(item.tierName ?? item.tier_name), thresholdCoinAmount: numberValue(item.thresholdCoinAmount ?? item.threshold_coin_amount), thresholdValidInviteCount: numberValue(item.thresholdValidInviteCount ?? item.threshold_valid_invite_count), reachedValue: numberValue(item.reachedValue ?? item.reached_value), rewardCoinAmount: numberValue(item.rewardCoinAmount ?? item.reward_coin_amount), status: stringValue(item.status), walletCommandId: stringValue(item.walletCommandId ?? item.wallet_command_id), walletTransactionId: stringValue(item.walletTransactionId ?? item.wallet_transaction_id), failureReason: stringValue(item.failureReason ?? item.failure_reason), grantedAtMs: numberValue(item.grantedAtMs ?? item.granted_at_ms), createdAtMs: numberValue(item.createdAtMs ?? item.created_at_ms), updatedAtMs: numberValue(item.updatedAtMs ?? item.updated_at_ms), }; } function stringValue(value: unknown) { return typeof value === "string" ? value : value === undefined || value === null ? "" : String(value); } function numberValue(value: unknown) { const number = Number(value || 0); return Number.isFinite(number) ? number : 0; }