import { useCallback, useEffect, useState } from 'react';

const languages = [
    { code: 'en', name: 'English', flag: '🇺🇸' },
    { code: 'fr', name: 'French', flag: '🇫🇷' },
    { code: 'sw', name: 'Kiswahili', flag: '🇰🇪' },
] as const;

type LanguageCode = (typeof languages)[number]['code'];

/** Trigger label — always “Language” in the active UI language, not the selected locale name. */
const languageTriggerLabel: Record<LanguageCode, string> = {
    en: 'Language',
    fr: 'Langue',
    sw: 'Lugha',
};

type LanguageSwitcherProps = {
    placement?: 'default' | 'attr' | 'mobile';
};

function isLanguageCode(value: string): value is LanguageCode {
    return languages.some((language) => language.code === value);
}

export function LanguageSwitcher({ placement = 'default' }: LanguageSwitcherProps) {
    const [currentLang, setCurrentLang] = useState<LanguageCode>('en');
    const [mounted, setMounted] = useState(false);
    const [isOpen, setIsOpen] = useState(false);

    const clearTranslateCookie = useCallback(() => {
        if (typeof window === 'undefined') {
            return;
        }

        const expireDate = 'Thu, 01 Jan 1970 00:00:00 UTC';
        const hostname = window.location.hostname;
        const rootDomain = hostname.split('.').slice(-2).join('.');

        [hostname, rootDomain, `.${rootDomain}`].forEach((domain) => {
            document.cookie = `googtrans=; expires=${expireDate}; path=/; domain=${domain}`;
            document.cookie = `googtrans=; expires=${expireDate}; path=/`;
        });
    }, []);

    const triggerGoogleTranslate = useCallback(
        (langCode: LanguageCode) => {
            if (typeof window === 'undefined') {
                return;
            }

            const tryTranslate = (): boolean => {
                const select = document.querySelector<HTMLSelectElement>('.goog-te-combo');
                if (!select) {
                    return false;
                }

                if (langCode === 'en') {
                    clearTranslateCookie();
                    window.location.reload();
                } else {
                    const cookieValue = `/en/${langCode}`;
                    const hostname = window.location.hostname;
                    const rootDomain = hostname.split('.').slice(-2).join('.');

                    [hostname, rootDomain, `.${rootDomain}`].forEach((domain) => {
                        try {
                            document.cookie = `googtrans=${cookieValue}; path=/; max-age=31536000; domain=${domain}`;
                        } catch {
                            /* localhost */
                        }
                    });
                    document.cookie = `googtrans=${cookieValue}; path=/; max-age=31536000`;

                    setTimeout(() => {
                        if (select.value !== langCode) {
                            select.value = langCode;
                            select.dispatchEvent(new Event('change', { bubbles: true, cancelable: true }));
                        }
                    }, 50);
                }

                return true;
            };

            if (!tryTranslate()) {
                setTimeout(() => tryTranslate() || setTimeout(tryTranslate, 500), 200);
            }
        },
        [clearTranslateCookie],
    );

    useEffect(() => {
        setMounted(true);
    }, []);

    useEffect(() => {
        if (!isOpen) {
            return;
        }

        const handleClickOutside = (event: MouseEvent): void => {
            if (!(event.target as HTMLElement).closest('.language-switcher-container')) {
                setIsOpen(false);
            }
        };

        document.addEventListener('click', handleClickOutside);

        return () => document.removeEventListener('click', handleClickOutside);
    }, [isOpen]);

    useEffect(() => {
        if (!mounted || typeof window === 'undefined') {
            return;
        }

        const saved = localStorage.getItem('preferredLanguage') ?? 'en';
        const savedLang = isLanguageCode(saved) ? saved : 'en';
        setCurrentLang(savedLang);

        if (savedLang === 'en') {
            clearTranslateCookie();

            const isTranslated =
                document.documentElement.classList.contains('translated-ltr') ||
                document.documentElement.classList.contains('translated-rtl');

            if (isTranslated && !sessionStorage.getItem('langResetInProgress')) {
                sessionStorage.setItem('langResetInProgress', 'true');
                clearTranslateCookie();
                window.location.reload();

                return;
            }

            if (sessionStorage.getItem('langResetInProgress')) {
                setTimeout(() => sessionStorage.removeItem('langResetInProgress'), 1000);
            }
        } else {
            const checkAndTrigger = (): void => {
                if (window.google?.translate) {
                    triggerGoogleTranslate(savedLang);
                } else {
                    setTimeout(checkAndTrigger, 100);
                }
            };

            setTimeout(checkAndTrigger, 300);
        }
    }, [mounted, clearTranslateCookie, triggerGoogleTranslate]);

    const changeLanguage = (langCode: LanguageCode): void => {
        setCurrentLang(langCode);
        localStorage.setItem('preferredLanguage', langCode);
        setIsOpen(false);
        window.dispatchEvent(new CustomEvent('languageChanged', { detail: { language: langCode } }));
        triggerGoogleTranslate(langCode);
    };

    const currentLanguage = languages.find((language) => language.code === currentLang) ?? languages[0];

    const rootClass =
        placement === 'attr'
            ? 'language-switcher-container language-switcher-container--attr'
            : placement === 'mobile'
              ? 'language-switcher-container language-switcher-container--mobile'
              : 'language-switcher-container';

    const triggerLabel = languageTriggerLabel[currentLang];

    if (!mounted) {
        return (
            <div className={`${rootClass} language-switcher-container--placeholder`} aria-hidden>
                <span className="language-switcher language-switcher--trigger">
                    <span className="language-name notranslate" translate="no">
                        {languageTriggerLabel.en}
                    </span>
                </span>
            </div>
        );
    }

    return (
        <div className={rootClass}>
            <button
                type="button"
                onClick={(event) => {
                    event.stopPropagation();
                    setIsOpen((open) => !open);
                }}
                className="language-switcher language-switcher--trigger"
                aria-label={`${triggerLabel} (current: ${currentLanguage.name})`}
                aria-expanded={isOpen}
                aria-haspopup="listbox"
            >
                <span className="language-name notranslate" translate="no">
                    {triggerLabel}
                </span>
                <i
                    className={`fas fa-chevron-${isOpen ? 'up' : 'down'} language-switcher-chevron`}
                    aria-hidden
                />
            </button>

            {isOpen ? (
                <div
                    className="language-dropdown notranslate"
                    translate="no"
                    role="listbox"
                    onClick={(event) => event.stopPropagation()}
                >
                    {languages.map((language) => (
                        <button
                            type="button"
                            key={language.code}
                            onClick={() => changeLanguage(language.code)}
                            className={`language-option notranslate ${language.code === currentLang ? 'is-active' : ''}`}
                            translate="no"
                            role="option"
                            aria-selected={language.code === currentLang}
                        >
                            <span className="language-flag" aria-hidden>
                                {language.flag}
                            </span>
                            <span className="language-option-label">{language.name}</span>
                            {language.code === currentLang ? (
                                <i className="fas fa-check language-option-check" aria-hidden />
                            ) : null}
                        </button>
                    ))}
                </div>
            ) : null}
        </div>
    );
}
