import { useState, useEffect } from 'react';
import { generateRealisticEmail } from "@/services/random-value/emailGenerator";
import { useTranslations } from "@/hooks/translations";
import { ELocalesPlacement } from "@/locales";
import { IFunnelPaymentVariant } from '@/api/resources/Session';

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<IFunnelPaymentVariant & { weight: number }>) => {
    const { translate } = useTranslations(ELocalesPlacement.EmailGenerator);
    const [displayEmails, setDisplayEmails] = useState<DisplayEmail[]>([]);
    const [countBoughtEmails, setCountBoughtEmails] = useState(758);
    const [emailsToDeleteQueue, setEmailsToDeleteQueue] = useState<EmailsToDelete[]>([]);

    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 };
};