import { API_ENDPOINTS, API_OPERATIONS, apiEndpointPath } from "@/shared/api/generated/endpoints";
import { apiRequest } from "@/shared/api/request";
import type { ApiPage, PageQuery } from "@/shared/api/types";

export interface RoomTurnoverRewardTierDto {
    tierId: number;
    tierCode: string;
    tierName: string;
    thresholdCoinSpent: number;
    rewardCoinAmount: number;
    status: string;
    sortOrder: number;
    createdAtMs?: number;
    updatedAtMs?: number;
}

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

export interface RoomTurnoverRewardConfigPayload {
    enabled: boolean;
    tiers: Array<{
        tier_id?: number;
        tier_code: string;
        tier_name: string;
        threshold_coin_spent: number;
        reward_coin_amount: number;
        status: string;
        sort_order: number;
    }>;
}

export interface RoomTurnoverRewardSettlementDto {
    settlementId: string;
    roomId: string;
    ownerUserId: string;
    ownerUser?: Record<string, unknown>;
    periodStartMs: number;
    periodEndMs: number;
    coinSpent: number;
    tierId: number;
    tierCode: string;
    thresholdCoinSpent: number;
    rewardCoinAmount: number;
    status: string;
    walletCommandId?: string;
    walletTransactionId?: string;
    failureReason?: string;
    settledAtMs?: number;
    createdAtMs?: number;
    updatedAtMs?: number;
}

export interface RoomTurnoverRewardSettlementQuery extends PageQuery {
    status?: string;
    keyword?: string;
    owner_user_keyword?: string;
    owner_user_id?: string;
}

type RawConfig = RoomTurnoverRewardConfigDto & Record<string, unknown>;
type RawTier = RoomTurnoverRewardTierDto & Record<string, unknown>;
type RawSettlement = RoomTurnoverRewardSettlementDto & Record<string, unknown>;

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

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

export function listRoomTurnoverRewardSettlements(
    query: RoomTurnoverRewardSettlementQuery = {},
): Promise<ApiPage<RoomTurnoverRewardSettlementDto>> {
    const endpoint = API_ENDPOINTS.listRoomTurnoverRewardSettlements;
    return apiRequest<ApiPage<RawSettlement>>(apiEndpointPath(API_OPERATIONS.listRoomTurnoverRewardSettlements), {
        method: endpoint.method,
        query,
    }).then((page) => ({
        ...page,
        items: (page.items || []).map(normalizeSettlement),
    }));
}

export function retryRoomTurnoverRewardSettlement(
    settlementId: string,
): Promise<RoomTurnoverRewardSettlementDto> {
    const endpoint = API_ENDPOINTS.retryRoomTurnoverRewardSettlement;
    return apiRequest<RawSettlement>(
        apiEndpointPath(API_OPERATIONS.retryRoomTurnoverRewardSettlement, { settlement_id: settlementId }),
        {
            method: endpoint.method,
        },
    ).then(normalizeSettlement);
}

function normalizeConfig(item: RawConfig): RoomTurnoverRewardConfigDto {
    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): RoomTurnoverRewardTierDto {
    return {
        tierId: numberValue(item.tierId ?? item.tier_id),
        tierCode: stringValue(item.tierCode ?? item.tier_code),
        tierName: stringValue(item.tierName ?? item.tier_name),
        thresholdCoinSpent: numberValue(item.thresholdCoinSpent ?? item.threshold_coin_spent),
        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 normalizeSettlement(item: RawSettlement): RoomTurnoverRewardSettlementDto {
    return {
        settlementId: stringValue(item.settlementId ?? item.settlement_id),
        roomId: stringValue(item.roomId ?? item.room_id),
        ownerUserId: stringValue(item.ownerUserId ?? item.owner_user_id),
        ownerUser: objectValue(item.ownerUser ?? item.owner_user),
        periodStartMs: numberValue(item.periodStartMs ?? item.period_start_ms),
        periodEndMs: numberValue(item.periodEndMs ?? item.period_end_ms),
        coinSpent: numberValue(item.coinSpent ?? item.coin_spent),
        tierId: numberValue(item.tierId ?? item.tier_id),
        tierCode: stringValue(item.tierCode ?? item.tier_code),
        thresholdCoinSpent: numberValue(item.thresholdCoinSpent ?? item.threshold_coin_spent),
        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),
        settledAtMs: numberValue(item.settledAtMs ?? item.settled_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;
}

function objectValue(value: unknown) {
    return value && typeof value === "object" && !Array.isArray(value) ? (value as Record<string, unknown>) : undefined;
}
