import dayjs from 'dayjs' import { formatAmountUnit } from '#lib/utils/number' import { usePackageStore, useUserPromotionStore, usePromotionStore, } from '#lib/stores' import { PromotionPlanEnum } from '#lib/enums' import type { PackageItem, PromotionUser } from '#lib/types' import { formatDate } from '#lib/utils' import { computed, ref } from 'vue' import { useNadal } from '#lib/composables' import { ROLLING_WHEN_USING_100K_PROMOTION } from '#lib/constants' /** * Composable to manage promotion-related state and actions. * * Provides reactive properties and methods for interacting with promotions, * including fetching promotion data, filtering packages, and handling modal states. * * @returns {Object} An object containing: * - Modal state properties and methods. * - Computed properties for promotion details. * - Functions for fetching and managing promotions. * @namespace */ export function usePromotion() { const { setOpenWithdrawUsingPromotionModal, setOpenUsingPromotionModal } = usePromotionStore() const isLoading = ref(false) // Reactive reference indicating if data is being loaded. const userPromotionStore = useUserPromotionStore() // Access promotion store. const storePackages = usePackageStore() // Access package store. const { promotion } = useNadal() // Computed properties for promotion user data and plan details. const promotionUser = computed(() => userPromotionStore.promotionUser) const promotionPlan = computed(() => userPromotionStore.getUserPlan()) const packageId = computed(() => userPromotionStore.getPackageId()) const isPromotionPlan = computed(() => Boolean(promotionPlan.value?.id)) /** * Checks if the user is using promotion commission. * @returns {boolean} True if the user is using promotion commission, otherwise false. */ const isCommissionType = computed(() => { if (!promotionPlan.value) return false return packageId.value === PromotionPlanEnum.COMMISSION }) /** * Checks if the user is using promotion. * @returns {boolean} True if the user is using promotion, otherwise false. */ const isUsingPromotion = computed(() => Boolean(packageId.value && !isCommissionType.value), ) /** * Checks if the current promotion package is a bonus package. * @returns {boolean} True if the promotion package is a bonus, otherwise false. */ const isBonus = computed( () => userPromotionStore.getPackageId() === PromotionPlanEnum.BONUS, ) const isCompletedPromotionBonus = computed(() => { const userPromotionPlan = userPromotionStore.getUserPlan() const result = isBonus && userPromotionPlan?.turnover && userPromotionPlan?.turnover >= ROLLING_WHEN_USING_100K_PROMOTION return Boolean(result) }) /* * Computed property to determine if the promotion plan is a welcome type. * @returns {boolean} True if the user is using welcome promotion, otherwise false. */ const isWelcomeType = computed(() => { if (!promotionPlan.value) { return false } return [ PromotionPlanEnum.WELCOME, PromotionPlanEnum.FIRST_50, PromotionPlanEnum.PROMOTION, ].includes(packageId.value as PromotionPlanEnum) }) // Computed property to determine if the rolling chart should be visible based on the promotion plan. const visibleRollingChart = computed(() => { if (!promotionPlan.value || packageId.value === undefined) { return false } return [ PromotionPlanEnum.WELCOME, PromotionPlanEnum.PROMOTION, PromotionPlanEnum.FIRST_50, ].includes(packageId.value as PromotionPlanEnum) }) // Computed property to get the list of promotion packages based on the current package ID. const promotionPackages = computed(() => { const listPromoPackage = storePackages.packages if (!packageId.value) { return listPromoPackage.filter( (item) => item.id !== PromotionPlanEnum.PROMOTION, ) } if (packageId.value === PromotionPlanEnum.COMMISSION) { return listPromoPackage.filter((item) => { return [ PromotionPlanEnum.COMMISSION, PromotionPlanEnum.PROMOTION, PromotionPlanEnum.FIRST_300, ].includes(item.id) }) } if (packageId.value === PromotionPlanEnum.BONUS) { return listPromoPackage.filter( (item) => item.id !== PromotionPlanEnum.PROMOTION && item.id !== PromotionPlanEnum.BONUS, ) } if (packageId.value === PromotionPlanEnum.WELCOME) { return listPromoPackage } // By default, show commission package (packageId = 1) return listPromoPackage.filter( (item) => item.id === PromotionPlanEnum.COMMISSION, ) }) // Computed property to format the promotion plan's time period. const timePromoteText = computed(() => { if (!promotionPlan.value) return null const expiredDate = formatDate( dayjs(promotionPlan.value.created_time).add(30, 'day'), ) const currentTime = formatDate(promotionPlan.value.created_time) return `${currentTime} - ${expiredDate}` }) // Computed properties to format and display various promotion-related amounts. const turnoverPromotionUser = computed(() => formatAmountUnit(promotionUser.value?.turnover ?? 0), ) const rollingPromotionUser = computed(() => formatAmountUnit(promotionUser.value?.rolling ?? 0), ) const depositAmount = computed(() => { if (!promotionPlan.value) return '' return formatAmountUnit( Number(promotionPlan.value?.deposit_amount) / 1000, 1, ) }) const totalAmount = computed(() => { if (!promotionPlan.value) return '' return formatAmountUnit( (Number(promotionPlan.value?.deposit_amount) + Number(promotionPlan.value?.promotion_amount)) / 1000, 1, ) }) const promotionPercent = computed(() => { if (promotionUser.value.multiplier === 0) { return 0 } return ( (Number(promotionUser.value.calculated_turnover) / Number(promotionUser.value.multiplier)) * 100 ) }) // Function to fetch user promotion details. const fetchUserPromotion = async (): Promise => { try { isLoading.value = true const data = await promotion.promotion() if (data) { userPromotionStore.setPromotionUser(data) } } catch (ex) { console.error(' ~ fetchUserPromotion ~ ex:', ex) } finally { isLoading.value = false } } // Function to fetch promotion packages. const fetchPromotionPackages = async (): Promise => { try { isLoading.value = true const data = await promotion.packages() if (data?.length) { storePackages.setPackages(data) } } catch (ex) { console.error(' ~ fetchPromotionPackages ~ ex:', ex) } finally { isLoading.value = false } } // Function to check if a bank note should be displayed based on package ID. const isShowBankNote = (packageId: string): boolean => { const hasPackage = promotionPackages.value.some( (item: PackageItem) => item.id === parseInt(packageId), ) return hasPackage && parseInt(packageId) !== PromotionPlanEnum.COMMISSION } // Function to cancel the current promotion plan. const onCancelPromotion = async (): Promise => { const planId = promotionPlan.value?.id const payload = { plan_id: planId } await promotion.cancel(payload) await fetchUserPromotion() await fetchPromotionPackages() } // Functions to open modals. const openModalWithdrawUsingPromotion = () => { setOpenWithdrawUsingPromotionModal(true) } const openModalUsingPromotion = () => { setOpenUsingPromotionModal(true) } return { isPromotionPlan, promotionUser, promotionPlan, isWelcomeType, isCommissionType, visibleRollingChart, isUsingPromotion, isCompletedPromotionBonus, isBonus, promotionPackages, timePromoteText, promotionPercent, turnoverPromotionUser, rollingPromotionUser, depositAmount, totalAmount, isLoading, packageId, fetchUserPromotion, fetchPromotionPackages, isShowBankNote, onCancelPromotion, openModalWithdrawUsingPromotion, openModalUsingPromotion, } }