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 FirstRechargeRewardTierDto {
    tierId: number;
    tierCode: string;
    tierName: string;
    minCoinAmount: number;
    maxCoinAmount: number;
    usdMinorAmount: number;
    googleProductId: string;
    discountPercent: number;
    resourceGroupId: number;
    status: string;
    sortOrder: number;
    createdAtMs?: number;
    updatedAtMs?: number;
}

export interface FirstRechargeRewardConfigDto {
    appCode?: string;
    enabled: boolean;
    tiers: FirstRechargeRewardTierDto[];
    updatedByAdminId?: number;
    createdAtMs?: number;
    updatedAtMs?: number;
}

export interface FirstRechargeRewardConfigPayload {
    enabled: boolean;
    tiers: Array<{
        tier_id?: number;
        tier_code: string;
        tier_name: string;
        min_coin_amount: number;
        max_coin_amount: number;
        usd_minor_amount: number;
        google_product_id: string;
        discount_percent: number;
        resource_group_id: number;
        status: string;
        sort_order: number;
    }>;
}

export interface FirstRechargeRewardClaimUserDto {
    userId?: string;
    displayUserId?: string;
    prettyDisplayUserId?: string;
    prettyId?: string;
    username?: string;
    avatar?: string;
}

export interface FirstRechargeRewardClaimDto {
    claimId: string;
    eventId?: string;
    transactionId?: string;
    commandId?: string;
    userId: string;
    user?: FirstRechargeRewardClaimUserDto;
    tierId?: number;
    tierCode?: string;
    resourceGroupId?: number;
    rechargeCoinAmount?: number;
    rechargeSequence?: number;
    rechargeType?: string;
    tierUsdMinorAmount?: number;
    googleProductId?: string;
    rechargeUsdMinor?: number;
    status?: string;
    walletCommandId?: string;
    walletGrantId?: string;
    failureReason?: string;
    rechargedAtMs?: number;
    grantedAtMs?: number;
    createdAtMs?: number;
    updatedAtMs?: number;
}

type RawConfig = FirstRechargeRewardConfigDto & Record<string, unknown>;
type RawTier = FirstRechargeRewardTierDto & Record<string, unknown>;
type RawClaim = FirstRechargeRewardClaimDto & Record<string, unknown>;

export function getFirstRechargeRewardConfig(): Promise<FirstRechargeRewardConfigDto> {
    const endpoint = API_ENDPOINTS.getFirstRechargeRewardConfig;
    return apiRequest<RawConfig>(apiEndpointPath(API_OPERATIONS.getFirstRechargeRewardConfig), {
        method: endpoint.method,
    }).then(normalizeConfig);
}

export function updateFirstRechargeRewardConfig(
    payload: FirstRechargeRewardConfigPayload,
): Promise<FirstRechargeRewardConfigDto> {
    const endpoint = API_ENDPOINTS.updateFirstRechargeRewardConfig;
    return apiRequest<RawConfig, FirstRechargeRewardConfigPayload>(
        apiEndpointPath(API_OPERATIONS.updateFirstRechargeRewardConfig),
        {
            body: payload,
            method: endpoint.method,
        },
    ).then(normalizeConfig);
}

export function listFirstRechargeRewardClaims(query: PageQuery = {}): Promise<ApiPage<FirstRechargeRewardClaimDto>> {
    const endpoint = API_ENDPOINTS.listFirstRechargeRewardClaims;
    return apiRequest<ApiPage<RawClaim>>(apiEndpointPath(API_OPERATIONS.listFirstRechargeRewardClaims), {
        method: endpoint.method,
        query,
    }).then((page) => ({
        ...page,
        items: (page.items || []).map(normalizeClaim),
    }));
}

function normalizeConfig(item: RawConfig): FirstRechargeRewardConfigDto {
    const rawTiers = Array.isArray(item.tiers) ? (item.tiers as RawTier[]) : [];
    return {
        appCode: stringValue(item.appCode ?? item.app_code),
        enabled: Boolean(item.enabled),
        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): FirstRechargeRewardTierDto {
    return {
        tierId: numberValue(item.tierId ?? item.tier_id),
        tierCode: stringValue(item.tierCode ?? item.tier_code),
        tierName: stringValue(item.tierName ?? item.tier_name),
        minCoinAmount: numberValue(item.minCoinAmount ?? item.min_coin_amount),
        maxCoinAmount: numberValue(item.maxCoinAmount ?? item.max_coin_amount),
        usdMinorAmount: numberValue(item.usdMinorAmount ?? item.usd_minor_amount),
        googleProductId: stringValue(item.googleProductId ?? item.google_product_id),
        discountPercent: numberValue(item.discountPercent ?? item.discount_percent),
        resourceGroupId: numberValue(item.resourceGroupId ?? item.resource_group_id),
        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): FirstRechargeRewardClaimDto {
    const rawUser = (item.user || {}) as Record<string, unknown>;
    return {
        claimId: stringValue(item.claimId ?? item.claim_id),
        eventId: stringValue(item.eventId ?? item.event_id),
        transactionId: stringValue(item.transactionId ?? item.transaction_id),
        commandId: stringValue(item.commandId ?? item.command_id),
        userId: stringValue(item.userId ?? item.user_id),
        user: {
            userId: stringValue(rawUser.userId ?? rawUser.user_id),
            displayUserId: stringValue(rawUser.displayUserId ?? rawUser.display_user_id),
            prettyDisplayUserId: stringValue(rawUser.prettyDisplayUserId ?? rawUser.pretty_display_user_id),
            prettyId: stringValue(rawUser.prettyId ?? rawUser.pretty_id),
            username: stringValue(rawUser.username),
            avatar: stringValue(rawUser.avatar),
        },
        tierId: numberValue(item.tierId ?? item.tier_id),
        tierCode: stringValue(item.tierCode ?? item.tier_code),
        resourceGroupId: numberValue(item.resourceGroupId ?? item.resource_group_id),
        rechargeCoinAmount: numberValue(item.rechargeCoinAmount ?? item.recharge_coin_amount),
        rechargeSequence: numberValue(item.rechargeSequence ?? item.recharge_sequence),
        rechargeType: stringValue(item.rechargeType ?? item.recharge_type),
        tierUsdMinorAmount: numberValue(item.tierUsdMinorAmount ?? item.tier_usd_minor_amount),
        googleProductId: stringValue(item.googleProductId ?? item.google_product_id),
        rechargeUsdMinor: numberValue(item.rechargeUsdMinor ?? item.recharge_usd_minor),
        status: stringValue(item.status),
        walletCommandId: stringValue(item.walletCommandId ?? item.wallet_command_id),
        walletGrantId: stringValue(item.walletGrantId ?? item.wallet_grant_id),
        failureReason: stringValue(item.failureReason ?? item.failure_reason),
        rechargedAtMs: numberValue(item.rechargedAtMs ?? item.recharged_at_ms),
        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;
}
