import { apiRequest } from "@/shared/api/request";

export interface VipLevelDto {
    level: number;
    name: string;
    status: string;
    priceCoin: number;
    durationMs: number;
    rewardResourceGroupId: number;
    sortOrder: number;
    rechargeGateRequired: boolean;
    requiredRechargeCoinAmount: number;
    userRechargeCoinAmount?: number;
    purchaseLockedReason?: string;
    createdAtMs?: number;
    updatedAtMs?: number;
}

export interface VipConfigDto {
    levels: VipLevelDto[];
    serverTimeMs?: number;
}

export interface VipConfigPayload {
    levels: Array<{
        level: number;
        name: string;
        status: string;
        priceCoin: number;
        durationMs: number;
        rewardResourceGroupId: number;
        sortOrder: number;
        requiredRechargeCoinAmount: number;
    }>;
}

export interface UserVipDto {
    userId: string;
    level: number;
    name: string;
    active: boolean;
    startedAtMs: number;
    expiresAtMs: number;
    updatedAtMs: number;
}

export interface VipRewardItemDto {
    resourceId: string;
    resourceCode: string;
    resourceType: string;
    name: string;
    quantity: number;
    expiresAtMs: number;
}

export interface VipGrantDto {
    transactionId: string;
    vip: UserVipDto;
    rewardItems: VipRewardItemDto[];
    serverTimeMs?: number;
}

export interface VipGrantPayload {
    commandId?: string;
    targetUserId: string;
    level: number;
    reason: string;
}

const path = "/v1/admin/activity/vip-levels";
const grantPath = "/v1/admin/activity/vip-grants";

export function getVipConfig(): Promise<VipConfigDto> {
    return apiRequest<RawConfig>(path).then(normalizeConfig);
}

export function updateVipConfig(payload: VipConfigPayload): Promise<VipConfigDto> {
    return apiRequest<RawConfig, VipConfigPayload>(path, { body: payload, method: "PUT" }).then(normalizeConfig);
}

export function grantVip(payload: VipGrantPayload): Promise<VipGrantDto> {
    return apiRequest<RawVipGrant, VipGrantPayload>(grantPath, { body: payload, method: "POST" }).then(
        normalizeVipGrant,
    );
}

type RawConfig = VipConfigDto & Record<string, unknown>;
type RawLevel = VipLevelDto & Record<string, unknown>;
type RawVipGrant = VipGrantDto & Record<string, unknown>;
type RawUserVip = UserVipDto & Record<string, unknown>;
type RawReward = VipRewardItemDto & Record<string, unknown>;

function normalizeConfig(item: RawConfig): VipConfigDto {
    const rawLevels = Array.isArray(item.levels) ? (item.levels as RawLevel[]) : [];
    return {
        levels: rawLevels.map(normalizeLevel),
        serverTimeMs: numberValue(item.serverTimeMs ?? item.server_time_ms),
    };
}

function normalizeLevel(item: RawLevel): VipLevelDto {
    const level = numberValue(item.level);
    return {
        level,
        name: stringValue(item.name) || `VIP${level}`,
        status: stringValue(item.status) || "disabled",
        priceCoin: numberValue(item.priceCoin ?? item.price_coin),
        durationMs: numberValue(item.durationMs ?? item.duration_ms),
        rewardResourceGroupId: numberValue(item.rewardResourceGroupId ?? item.reward_resource_group_id),
        sortOrder: numberValue(item.sortOrder ?? item.sort_order),
        rechargeGateRequired: Boolean(item.rechargeGateRequired ?? item.recharge_gate_required ?? level >= 6),
        requiredRechargeCoinAmount: numberValue(item.requiredRechargeCoinAmount ?? item.required_recharge_coin_amount),
        userRechargeCoinAmount: numberValue(item.userRechargeCoinAmount ?? item.user_recharge_coin_amount),
        purchaseLockedReason: stringValue(item.purchaseLockedReason ?? item.purchase_locked_reason),
        createdAtMs: numberValue(item.createdAtMs ?? item.created_at_ms),
        updatedAtMs: numberValue(item.updatedAtMs ?? item.updated_at_ms),
    };
}

function normalizeVipGrant(item: RawVipGrant): VipGrantDto {
    const rewardItems = Array.isArray(item.rewardItems) ? (item.rewardItems as RawReward[]) : [];
    return {
        transactionId: stringValue(item.transactionId ?? item.transaction_id),
        vip: normalizeUserVip((item.vip || {}) as RawUserVip),
        rewardItems: rewardItems.map(normalizeRewardItem),
        serverTimeMs: numberValue(item.serverTimeMs ?? item.server_time_ms),
    };
}

function normalizeUserVip(item: RawUserVip): UserVipDto {
    return {
        userId: stringValue(item.userId ?? item.user_id),
        level: numberValue(item.level),
        name: stringValue(item.name),
        active: Boolean(item.active),
        startedAtMs: numberValue(item.startedAtMs ?? item.started_at_ms),
        expiresAtMs: numberValue(item.expiresAtMs ?? item.expires_at_ms),
        updatedAtMs: numberValue(item.updatedAtMs ?? item.updated_at_ms),
    };
}

function normalizeRewardItem(item: RawReward): VipRewardItemDto {
    return {
        resourceId: stringValue(item.resourceId ?? item.resource_id),
        resourceCode: stringValue(item.resourceCode ?? item.resource_code),
        resourceType: stringValue(item.resourceType ?? item.resource_type),
        name: stringValue(item.name),
        quantity: numberValue(item.quantity),
        expiresAtMs: numberValue(item.expiresAtMs ?? item.expires_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;
}
