import { useState, useEffect } from 'react'; import { IPaywallProduct } from "@/api/resources/Paywall"; import { generateRealisticEmail } from "@/services/random-value/emailGenerator"; import { useTranslations } from "@/hooks/translations"; import { ELocalesPlacement } from "@/locales"; interface DisplayEmail { email: string; price: number; id: number; willBeRemoved: boolean; } interface EmailsToDelete { emails: DisplayEmail[]; deleteAt: number; markAt: number; marked: boolean; } export const useEmailsGeneration = (products: Array) => { const { translate } = useTranslations(ELocalesPlacement.EmailGenerator); const [displayEmails, setDisplayEmails] = useState([]); const [countBoughtEmails, setCountBoughtEmails] = useState(758); const [emailsToDeleteQueue, setEmailsToDeleteQueue] = useState([]); const minEmails = 1; const maxEmails = 5; const getRandomProduct = () => { const totalWeight = products.reduce((sum, product) => sum + (product.weight || 1), 0); let random = Math.random() * totalWeight; for (const product of products) { random -= (product.weight || 1); if (random <= 0) return product; } return products[0]; } const createEmail = () => { const product = getRandomProduct(); return { email: generateRealisticEmail( translate("firstNames").split(",") || [], translate("lastNames").split(",") || [], translate("domains").split(",") || [] ), price: (product.trialPrice || 0) / 100, id: Date.now() + Math.random(), willBeRemoved: false }; } // creating emails useEffect(() => { if (!products?.length) return; addEmails(3); return () => setDisplayEmails([]); }, [products]); const addEmails = (countEmails?: number) => { const addEmailsTimeout = 3000 + Math.random() * 2000; const count = !!countEmails ? countEmails : Math.random() < 0.6 ? 1 : 2; const _newEmails = Array(count).fill(null).map(createEmail); setDisplayEmails(prev => { const updatedEmails = [...prev, ..._newEmails].slice(-maxEmails); if (updatedEmails.length < minEmails) { const additionalCount = minEmails - updatedEmails.length; const additionalEmails = Array(additionalCount).fill(null).map(createEmail); return [...updatedEmails, ...additionalEmails]; } return updatedEmails; }); const now = Date.now(); setEmailsToDeleteQueue(prev => [...prev, ..._newEmails.map((value) => { const deleteTime = 3000 + Math.random() * 10000; return { emails: [value], deleteAt: now + deleteTime, markAt: now + deleteTime - 1500, marked: false } })]); const timeoutAddEmails = setTimeout(() => { addEmails(); clearTimeout(timeoutAddEmails); }, addEmailsTimeout); } useEffect(() => { if (emailsToDeleteQueue.length === 0) return; const checkQueue = () => { const now = Date.now(); setEmailsToDeleteQueue(prev => { const updatedQueue = [...prev]; let hasChanges = false; updatedQueue.forEach(item => { if (displayEmails.length <= minEmails) return; if (!item.marked && now >= item.markAt) { markEmails(item.emails); item.marked = true; hasChanges = true; } if (now >= item.deleteAt) { deleteEmails(item.emails); hasChanges = true; } }); return hasChanges ? updatedQueue.filter(item => now < item.deleteAt) : updatedQueue; }); }; const interval = setInterval(checkQueue, 100); return () => clearInterval(interval); }, [emailsToDeleteQueue]); const deleteEmails = (emailsToDelete: DisplayEmail[]) => { setDisplayEmails(prev => prev.filter(email => !emailsToDelete.some(e => e.id === email.id)) ); setCountBoughtEmails(prev => prev + emailsToDelete.length); } const markEmails = (emailsToMark: DisplayEmail[]) => { setDisplayEmails(prev => prev.map(email => emailsToMark.some(e => e.id === email.id) ? { ...email, willBeRemoved: true } : email ) ); } return { displayEmails, countBoughtEmails }; };