import { getVideoCreditCostFromConfig, type VideoImageGenConfigLike } from "@/lib/ai/video-model-config"; export type DiscountableImageGenConfigLike = VideoImageGenConfigLike & { creditCostPerImage?: number | null; creditDiscountRate?: number | null; }; function normalizeRoundedCost(value: unknown) { const normalized = Number(value); if (!Number.isFinite(normalized)) return 0; return Math.max(0, Math.round(normalized)); } export function normalizeImageModelCreditDiscountRate(value: unknown) { const normalized = Number(value); if (!Number.isFinite(normalized)) return null; const rounded = Math.round(normalized * 10) / 10; if (rounded <= 0 || rounded >= 10) return null; return rounded; } export function formatImageModelCreditDiscountLabel(value: unknown) { const normalized = normalizeImageModelCreditDiscountRate(value); if (normalized === null) return null; const displayValue = Number.isInteger(normalized) ? String(normalized) : normalized.toFixed(1).replace(/\.0$/, ""); return `${displayValue}折`; } export function getImageModelCreditDiscountLabel( config: DiscountableImageGenConfigLike | null | undefined ) { return formatImageModelCreditDiscountLabel(config?.creditDiscountRate); } export function applyImageModelCreditDiscount( rawCost: unknown, config: DiscountableImageGenConfigLike | null | undefined ) { const baseCost = normalizeRoundedCost(rawCost); if (baseCost <= 0) return 0; const normalizedDiscountRate = normalizeImageModelCreditDiscountRate( config?.creditDiscountRate ); if (normalizedDiscountRate === null) return baseCost; return Math.max(0, Math.round((baseCost * normalizedDiscountRate) / 10)); } export function getGenerationCreditCostFromImageGenConfig( config: DiscountableImageGenConfigLike | null | undefined, target: "image" | "video", options?: { duration?: number | null; resolution?: string | null } ) { const sourceValue = target === "video" ? (() => { const resolvedVideoCost = getVideoCreditCostFromConfig( config, options?.duration, options?.resolution ); if (resolvedVideoCost > 0) return resolvedVideoCost; return config?.creditCostPerVideo ?? config?.creditCostPerImage ?? 0; })() : config?.creditCostPerImage ?? 0; return applyImageModelCreditDiscount(sourceValue, config); } export function getImageCreditCostFromConfig( config: DiscountableImageGenConfigLike | null | undefined ) { return getGenerationCreditCostFromImageGenConfig(config, "image"); } export function getModelGenerationCreditCost( modelConfig: { imageGenConfig?: DiscountableImageGenConfigLike | null } | null | undefined, target: "image" | "video", options?: { duration?: number | null; resolution?: string | null } ) { return getGenerationCreditCostFromImageGenConfig( modelConfig?.imageGenConfig, target, options ); } export function normalizeImageGenPricingConfig< T extends DiscountableImageGenConfigLike | null | undefined, >(config: T): T { if (!config) return config; const normalizedDiscountRate = normalizeImageModelCreditDiscountRate( config.creditDiscountRate ); return { ...config, creditDiscountRate: normalizedDiscountRate ?? undefined, } as T; }