import { useGames, useCheckGame } from '#lib/composables' import { AppDataEnum, CasinoProviderEnum } from '#lib/enums' import type { CasinoGameItem, CasinoResponseItem, GamesRequestPayload, } from '#lib/types/game' import { computed, ref } from 'vue' import { useApiFetch } from '#lib/composables/service/use-api-fetch' import { LIVE_CASINO_API } from '#lib/configs' import { useAsyncData, useNuxtData, useRoute } from 'nuxt/app' import type { Metadata } from '#lib/types' interface Props { gameLimit: number key?: string } /** * Composable for managing casino games including fetching, filtering, and playing games. * @param {Props} props - The properties for configuring the casino composable. * @param {number} props.gameLimit - The maximum number of games to display per page. * @returns {Object} An object containing methods and reactive properties related to casino games. * @namespace */ export function useCasino(props: Props) { const { playGame } = useGames() const { request } = useApiFetch() const { showMaintenanceProvider } = useCheckGame() const selectedProvider = ref() const currentPage = ref(1) const perPage = ref(props.gameLimit) const route = useRoute() const { data: providers } = useNuxtData( AppDataEnum.LiveCasinoProviders, ) const { data: categories } = useNuxtData( AppDataEnum.LiveCasinoCategories, ) const { data: gameData } = useNuxtData<{ liveCasinoData: CasinoGameItem[] totalGames: number }>(AppDataEnum.LiveCasino + route.path) const liveCasinoData = computed(() => { return gameData.value?.liveCasinoData ?? [] }) const totalGames = computed(() => { return gameData.value?.totalGames ?? 0 }) const allCasinoGames = computed(() => { if (!liveCasinoData.value) { return [] } const slugProvides = providers.value?.map((item) => { return item.slug }) return liveCasinoData.value.filter((item) => !item.provider || slugProvides?.includes(item.provider), ) }) /** * Computed property that returns filtered live casino games based on the selected provider. * @returns {CasinoGameItem[]} The filtered list of live casino games. */ const liveCasinoGames = computed(() => { let data = [...allCasinoGames.value] if (selectedProvider.value) { data = data.filter((item) => item.provider === selectedProvider.value) } return data }) /** * Generates the URL location string based on the casino game item and its provider. * @param {CasinoGameItem} item - The casino game item. * @returns {string} The URL location string. */ const getURLLocation = (item: CasinoGameItem): string => { switch (item.provider) { case CasinoProviderEnum.VIVO: { let application = item.application || (item.category && item.category[0]) || '' application = application.replace('-', '') if (item.tableCode) { return `&application=${application}&tableid=${item.tableCode}` } return '' } case CasinoProviderEnum.EBET: { return `&redirecturl=${window.location}` } default: return '' } } /** * Initiates the game play for a casino game item based on its provider. * @param {CasinoGameItem} item - The casino game item to play. * @returns {Promise} A promise that resolves when the game play has been initiated. */ const playCasinoGame = async ( item: CasinoGameItem, moneyRequired: boolean = true, ): Promise => { playGame({ provider: item.provider, gameId: item.tableCode ?? item.tableId ?? item.gameId, urlLocation: getURLLocation(item), gameType: item.gameType ?? item.category?.[0] ?? '', newTab: true, promotionPrevent: true, promotionPrevent100K: true, loginRequired: true, moneyRequired, withoutIframe: true, isMaintenance: item.isMaintenance || item.isMaintain, apiUrl: item?.apiUrl ?? '' }) } /** * Filters the casino games based on the provided payload. * @param {Metadata} [metaData] - The response metadata containing filtering options. * @param {GamesRequestPayload} [payload] - The payload containing filtering options. */ const filterCasinoGames = ( metaData: Metadata, payload: GamesRequestPayload, ): void => { const limit = payload?.limit || props.gameLimit const paged = payload?.paged || 1 currentPage.value = paged perPage.value = limit selectedProvider.value = payload?.prov } /** * Fetches the live casino games based on the provided payload. * @param {GamesRequestPayload} payload - The payload containing request parameters. * @returns {Promise} A promise that resolves with the live casino games or undefined. */ const fetchLiveCasino = async ( payload: GamesRequestPayload, ): Promise => { const { data } = await useAsyncData( AppDataEnum.LiveCasino + (props.key ?? route.path), async () => { try { const response = await request( LIVE_CASINO_API.LIVE_CASINO, payload, ) filterCasinoGames(response.metaData, payload) return { liveCasinoData: response.data, totalGames: response.metaData.total, } } catch { return { liveCasinoData: [], totalGames: 0, } } }, ) return data.value?.liveCasinoData ?? null } /** * Fetches the live casino games without filtering based on providers. * @param {GamesRequestPayload} payload - The payload containing request parameters. * @returns {Promise} A promise that resolves with the live casino games or undefined. */ const requestFetchLiveCasino = async ( payload: GamesRequestPayload, ): Promise => { const { data } = await request( LIVE_CASINO_API.LIVE_CASINO, payload, ) return data } /** * Fetches the live casino games without filtering based on providers. * @param {GamesRequestPayload} payload - The payload containing request parameters. * @returns {Promise} A promise that resolves with the live casino games or undefined. */ const fetchLiveCasinoIndirect = async ( payload: GamesRequestPayload, ): Promise => { const { data } = await useAsyncData(AppDataEnum.LiveCasino, async () => { try { const { data } = await request( LIVE_CASINO_API.LIVE_CASINO, payload, ) return data } catch { return [] } }) return data.value } /** * Fetches casino categories based on the provided payload. * @param {GamesRequestPayload} payload - The payload containing request parameters. * @returns {Promise} A promise that resolves with the casino categories. */ const fetchCasinoCategories = async ( payload: GamesRequestPayload, ): Promise => { const { data } = await useAsyncData( AppDataEnum.LiveCasinoCategories, async () => { try { const { data } = await request< GamesRequestPayload, CasinoResponseItem[] >(LIVE_CASINO_API.CATEGORIES, payload) return data } catch { return [] } }, ) return data.value! } /** * Fetches casino providers based on the provided payload. * @param {GamesRequestPayload} payload - The payload containing request parameters. * @returns {Promise} A promise that resolves with the casino providers. */ const fetchCasinoProviders = async ( payload: GamesRequestPayload, ): Promise => { try { const { data } = await useAsyncData( AppDataEnum.LiveCasinoProviders, async () => { const response = await request< GamesRequestPayload, CasinoResponseItem[] >(LIVE_CASINO_API.PROVIDERS, payload) return response.data }, ) return data.value! } catch { return [] } } /** * Fetches data for casino games including providers, categories, and live casino games. * @param {GamesRequestPayload} payload - The payload containing request parameters. * @returns {Promise} A promise that resolves when the data has been fetched. */ const fetchData = async (payload: GamesRequestPayload) => { await Promise.all([ fetchCasinoProviders(payload), fetchLiveCasino(payload), fetchCasinoCategories(payload), ]) } return { categories, providers, liveCasinoGames, totalGames, currentPage, fetchData, filterCasinoGames, playCasinoGame, fetchLiveCasino, fetchCasinoProviders, fetchCasinoCategories, showMaintenanceProvider, fetchLiveCasinoIndirect, requestFetchLiveCasino, } }