import type { Package } from '../../api'; type PackageChange = { isUpgrade: boolean; isDowngrade: boolean; }; function collectFeatures(pkg: Package | null): Set { if (!pkg?.features) { return new Set(); } return new Set(Object.entries(pkg.features).filter(([, enabled]) => enabled).map(([key]) => key)); } function compareLimit(candidate: number | null, active: number | null): number { if (active === null) { return candidate === null ? 0 : -1; } if (candidate === null) { return 1; } if (candidate > active) return 1; if (candidate < active) return -1; return 0; } export function classifyPackageChange(pkg: Package, active: Package | null): PackageChange { if (!active) { return { isUpgrade: false, isDowngrade: false }; } const activeFeatures = collectFeatures(active); const candidateFeatures = collectFeatures(pkg); const hasFeatureUpgrade = Array.from(candidateFeatures).some((feature) => !activeFeatures.has(feature)); const hasFeatureDowngrade = Array.from(activeFeatures).some((feature) => !candidateFeatures.has(feature)); const limitKeys: Array = ['max_photos', 'max_guests', 'gallery_days']; let hasLimitUpgrade = false; let hasLimitDowngrade = false; limitKeys.forEach((key) => { const candidateLimit = pkg[key] ?? null; const activeLimit = active[key] ?? null; const delta = compareLimit(candidateLimit, activeLimit); if (delta > 0) { hasLimitUpgrade = true; } else if (delta < 0) { hasLimitDowngrade = true; } }); const hasUpgrade = hasFeatureUpgrade || hasLimitUpgrade; const hasDowngrade = hasFeatureDowngrade || hasLimitDowngrade; if (hasUpgrade) { return { isUpgrade: true, isDowngrade: false }; } if (hasDowngrade) { return { isUpgrade: false, isDowngrade: true }; } return { isUpgrade: false, isDowngrade: false }; } export function selectRecommendedPackageId( packages: Package[], feature: string | null, activePackage: Package | null ): number | null { if (!feature) { return null; } const candidates = packages.filter((pkg) => pkg.features?.[feature]); if (candidates.length === 0) { return null; } const upgrades = candidates.filter((pkg) => classifyPackageChange(pkg, activePackage).isUpgrade); const pool = upgrades.length ? upgrades : candidates; const sorted = [...pool].sort((a, b) => a.price - b.price); return sorted[0]?.id ?? null; }