import { cache } from 'react'; import { getAnalysisElementMedusaProductIds } from '@/utils/medusa-product'; import { listProductTypes, listProducts } from '@lib/data/products'; import { listRegions } from '@lib/data/regions'; import type { StoreProduct } from '@medusajs/types'; import type { AccountWithParams } from '@kit/accounts/types/accounts'; import type { AnalysisPackageWithVariant } from '@kit/shared/components/select-analysis-package'; import PersonalCode from '~/lib/utils'; import { loadCurrentUserAccount } from './load-user-account'; async function countryCodesLoader() { const countryCodes = await listRegions().then((regions) => regions?.map((r) => r.countries?.map((c) => c.iso_2)).flat(), ); return countryCodes ?? []; } export const loadCountryCodes = cache(countryCodesLoader); async function productTypesLoader() { const { productTypes } = await listProductTypes(); return productTypes ?? []; } export const loadProductTypes = cache(productTypesLoader); function userSpecificVariantLoader({ account, }: { account: AccountWithParams; }) { const { personal_code: personalCode } = account; if (!personalCode) { throw new Error('Personal code not found'); } const { ageRange, gender: { value: gender }, } = PersonalCode.parsePersonalCode(personalCode); return ({ product }: { product: StoreProduct }) => { const variants = product.variants; if (!variants) { return null; } const variant = variants.find((v) => v.options?.every((o) => [ageRange, gender].includes(o.value)), ); if (!variant) { return null; } return variant; }; } async function analysisPackageElementsLoader({ analysisPackagesWithVariant, countryCode, }: { analysisPackagesWithVariant: AnalysisPackageWithVariant[]; countryCode: string; }) { const analysisElementMedusaProductIds = getAnalysisElementMedusaProductIds( analysisPackagesWithVariant, ); if (analysisElementMedusaProductIds.length === 0) { return []; } const { response: { products }, } = await listProducts({ countryCode, queryParams: { id: analysisElementMedusaProductIds, limit: 100, order: 'title', }, }); const standardPackage = analysisPackagesWithVariant.find( ({ isStandard }) => isStandard, ); const standardPlusPackage = analysisPackagesWithVariant.find( ({ isStandardPlus }) => isStandardPlus, ); const premiumPackage = analysisPackagesWithVariant.find( ({ isPremium }) => isPremium, ); if (!standardPackage || !standardPlusPackage || !premiumPackage) { return []; } const standardPackageAnalyses = getAnalysisElementMedusaProductIds([ standardPackage, ]); const standardPlusPackageAnalyses = getAnalysisElementMedusaProductIds([ standardPlusPackage, ]); const premiumPackageAnalyses = getAnalysisElementMedusaProductIds([ premiumPackage, ]); return products.map(({ id, title, description }) => ({ id, title, description, isIncludedInStandard: standardPackageAnalyses.includes(id), isIncludedInStandardPlus: standardPlusPackageAnalyses.includes(id), isIncludedInPremium: premiumPackageAnalyses.includes(id), })); } async function analysisPackagesWithVariantLoader({ account, countryCode, }: { account: AccountWithParams; countryCode: string; }) { const productTypes = await loadProductTypes(); const productType = productTypes.find( ({ metadata }) => metadata?.handle === 'analysis-packages', ); if (!productType) { return null; } const analysisPackagesResponse = await listProducts({ countryCode, queryParams: { limit: 100, 'type_id[0]': productType.id }, }); const getVariant = userSpecificVariantLoader({ account }); const analysisPackagesWithVariant = analysisPackagesResponse.response.products.reduce((acc, product) => { const variant = getVariant({ product }); if (!variant) { return acc; } return [ ...acc, { variant, variantId: variant.id, nrOfAnalyses: getAnalysisElementMedusaProductIds([ { ...product, variant }, ]).length, price: variant.calculated_price?.calculated_amount ?? 0, title: product.title, subtitle: product.subtitle, description: product.description, metadata: product.metadata, isStandard: product.metadata?.analysisPackageTier === 'standard', isStandardPlus: product.metadata?.analysisPackageTier === 'standard-plus', isPremium: product.metadata?.analysisPackageTier === 'premium', }, ]; }, [] as AnalysisPackageWithVariant[]); return analysisPackagesWithVariant; } async function analysisPackagesLoader() { const { account } = await loadCurrentUserAccount(); if (!account) { throw new Error('Account not found'); } const countryCodes = await loadCountryCodes(); const countryCode = countryCodes[0]!; const analysisPackagesWithVariant = await analysisPackagesWithVariantLoader({ account, countryCode, }); if (!analysisPackagesWithVariant) { return { analysisPackageElements: [], analysisPackages: [], countryCode }; } const analysisPackageElements = await analysisPackageElementsLoader({ analysisPackagesWithVariant, countryCode, }); return { analysisPackageElements, analysisPackages: analysisPackagesWithVariant, countryCode, }; } export const loadAnalysisPackages = cache(analysisPackagesLoader);