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

export type VipProgramType = "legacy_timed" | "tiered_privilege_v1";
export type VipBenefitInheritancePolicy = "target_only";

export interface VipProgramDto {
    appCode: string;
    programType: VipProgramType;
    levelCount: number;
    status: string;
    configVersion?: number;
    sameLevelExpiryPolicy?: string;
    upgradeExpiryPolicy?: string;
    downgradePurchasePolicy?: string;
    benefitInheritancePolicy?: VipBenefitInheritancePolicy;
    grantMode?: string;
    trialCardEnabled?: boolean;
    createdAtMs?: number;
    updatedAtMs?: number;
    benefits?: VipBenefitDto[];
}

export interface VipProgramPayload {
    programType: VipProgramType;
    levelCount: number;
    sameLevelExpiryPolicy: string;
    upgradeExpiryPolicy: string;
    downgradePurchasePolicy: string;
    benefitInheritancePolicy: VipBenefitInheritancePolicy;
    grantMode: string;
    trialCardEnabled: boolean;
    status: string;
}

interface VipProgramUpdatePayload {
    config: VipProgramPayload;
}

export interface VipBenefitDto {
    benefitCode: string;
    name: string;
    benefitType: string;
    unlockLevel: number;
    status: string;
    trialEnabled: boolean;
    resourceId: number;
    resourceType: string;
    executionScope: string;
    autoEquip: boolean;
    sortOrder: number;
    metadataJson: string;
}

export interface VipLevelDto {
    level: number;
    name: string;
    status: string;
    priceCoin: number;
    durationMs: number;
    rewardResourceGroupId: number;
    sortOrder: number;
    benefits: VipBenefitDto[];
    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;
        benefits: VipBenefitDto[];
    }>;
}

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;
}

export interface VipTrialCardGrantPayload {
    commandId?: string;
    targetUserId: string;
    level: number;
    resourceId?: number;
    durationMs: number;
    reason: string;
}

export function getVipProgram(): Promise<VipProgramDto> {
    const endpoint = API_ENDPOINTS.getVipProgram;
    return apiRequest<RawVipProgramResponse>(apiEndpointPath(API_OPERATIONS.getVipProgram), {
        method: endpoint.method,
    }).then(normalizeVipProgramResponse);
}

export function updateVipProgram(payload: VipProgramPayload): Promise<VipProgramDto> {
    const endpoint = API_ENDPOINTS.updateVipProgram;
    return apiRequest<RawVipProgramResponse, VipProgramUpdatePayload>(
        apiEndpointPath(API_OPERATIONS.updateVipProgram),
        {
            body: { config: payload },
            method: endpoint.method,
        },
    ).then(normalizeVipProgramResponse);
}

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

export function updateVipConfig(payload: VipConfigPayload): Promise<VipConfigDto> {
    const endpoint = API_ENDPOINTS.updateVipConfig;
    return apiRequest<RawConfig, VipConfigPayload>(apiEndpointPath(API_OPERATIONS.updateVipConfig), {
        // 金币返现只属于付费 VIP；API 边界再收敛一次，避免未来调用方绕过页面控件恢复体验卡返现。
        body: enforceVipBenefitBoundaries(payload),
        method: endpoint.method,
    }).then(normalizeConfig);
}

export function grantVip(payload: VipGrantPayload): Promise<VipGrantDto> {
    const endpoint = API_ENDPOINTS.grantVip;
    return apiRequest<RawVipGrant, VipGrantPayload>(apiEndpointPath(API_OPERATIONS.grantVip), {
        body: payload,
        method: endpoint.method,
    }).then(normalizeVipGrant);
}

export function grantVipTrialCard(payload: VipTrialCardGrantPayload): Promise<unknown> {
    const endpoint = API_ENDPOINTS.grantVipTrialCard;
    return apiRequest<unknown, VipTrialCardGrantPayload>(apiEndpointPath(API_OPERATIONS.grantVipTrialCard), {
        body: payload,
        method: endpoint.method,
    });
}

type RawVipProgram = VipProgramDto & Record<string, unknown>;
type RawVipProgramResponse = RawVipProgram & {
    benefits?: RawBenefit[];
    config?: RawVipProgram;
    program_config?: RawVipProgram;
};
type RawConfig = VipConfigDto & Record<string, unknown>;
type RawLevel = VipLevelDto & Record<string, unknown>;
type RawBenefit = VipBenefitDto & Record<string, unknown>;
type RawVipGrant = VipGrantDto & Record<string, unknown>;
type RawUserVip = UserVipDto & Record<string, unknown>;
type RawReward = VipRewardItemDto & Record<string, unknown>;

function normalizeVipProgram(item: RawVipProgram): VipProgramDto {
    const programType = stringValue(item.programType ?? item.program_type);
    return {
        appCode: stringValue(item.appCode ?? item.app_code),
        programType: programType === "tiered_privilege_v1" ? "tiered_privilege_v1" : "legacy_timed",
        levelCount: numberValue(item.levelCount ?? item.level_count),
        status: stringValue(item.status) || "active",
        configVersion: numberValue(item.configVersion ?? item.config_version),
        sameLevelExpiryPolicy: stringValue(item.sameLevelExpiryPolicy ?? item.same_level_expiry_policy),
        upgradeExpiryPolicy: stringValue(item.upgradeExpiryPolicy ?? item.upgrade_expiry_policy),
        downgradePurchasePolicy: stringValue(item.downgradePurchasePolicy ?? item.downgrade_purchase_policy),
        // 滚动发布期间即使旧服务仍回 cumulative，前端也只暴露并回传当前唯一合法策略。
        benefitInheritancePolicy: "target_only",
        grantMode: stringValue(item.grantMode ?? item.grant_mode),
        trialCardEnabled: booleanValue(item.trialCardEnabled ?? item.trial_card_enabled),
        createdAtMs: numberValue(item.createdAtMs ?? item.created_at_ms),
        updatedAtMs: numberValue(item.updatedAtMs ?? item.updated_at_ms),
    };
}

function normalizeVipProgramResponse(item: RawVipProgramResponse): VipProgramDto {
    const config = item.config ?? item.program_config;
    const program = normalizeVipProgram((config && typeof config === "object" ? config : item) as RawVipProgram);
    return {
        ...program,
        benefits: Array.isArray(item.benefits) ? item.benefits.map(normalizeBenefit) : [],
    };
}

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);
    const rawBenefits = Array.isArray(item.benefits) ? (item.benefits as RawBenefit[]) : [];
    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),
        benefits: rawBenefits.map(normalizeBenefit),
        rechargeGateRequired: false,
        requiredRechargeCoinAmount: 0,
        userRechargeCoinAmount: 0,
        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 normalizeBenefit(item: RawBenefit): VipBenefitDto {
    const benefitCode = stringValue(item.benefitCode ?? item.benefit_code);
    return {
        benefitCode,
        name: stringValue(item.name),
        benefitType: stringValue(item.benefitType ?? item.benefit_type) || "function",
        unlockLevel: numberValue(item.unlockLevel ?? item.unlock_level),
        status: stringValue(item.status) || "disabled",
        // 历史脏数据可能把金币返现写成体验可用；读取时立即纠正，避免错误状态进入编辑表单。
        trialEnabled:
            benefitCode === "daily_coin_rebate" ? false : booleanValue(item.trialEnabled ?? item.trial_enabled),
        resourceId: numberValue(item.resourceId ?? item.resource_id),
        resourceType: stringValue(item.resourceType ?? item.resource_type),
        executionScope: stringValue(item.executionScope ?? item.execution_scope) || "wallet",
        autoEquip: booleanValue(item.autoEquip ?? item.auto_equip),
        sortOrder: numberValue(item.sortOrder ?? item.sort_order),
        metadataJson: stringValue(item.metadataJson ?? item.metadata_json) || "{}",
    };
}

function enforceVipBenefitBoundaries(payload: VipConfigPayload): VipConfigPayload {
    return {
        ...payload,
        levels: payload.levels.map((level) => ({
            ...level,
            benefits: level.benefits.map((benefit) =>
                benefit.benefitCode === "daily_coin_rebate" ? { ...benefit, trialEnabled: false } : benefit,
            ),
        })),
    };
}

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: booleanValue(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;
}

function booleanValue(value: unknown) {
    if (typeof value === "string") {
        return value === "true" || value === "1";
    }
    return Boolean(value);
}
