components/ui/LanguageSwitcher.jsx

import React, {useEffect, useRef, useState} from "react";
import {useTranslation} from "react-i18next";

const flags = {
    en: "https://flagcdn.com/w20/gb.png",
    it: "https://flagcdn.com/w20/it.png",
};

const languageLabels = {
    en: "English",
    it: "Italiano",
};

/**
 * LanguageSwitcher component provides a dropdown button to switch between supported languages.
 *
 * Shows current language with corresponding flag and allows user to select a different language
 * from a dropdown menu. On selection, the language changes via `i18n.changeLanguage`.
 *
 * Supported languages: English ("en") and Italian ("it").
 *
 * @component
 * @module components/ui/LanguageSwitcher
 * @returns {JSX.Element} The language switcher UI.
 */
export default function LanguageSwitcher() {
    const {i18n} = useTranslation();
    const [open, setOpen] = useState(false);
    const dropdownRef = useRef(null);

    const toggleDropdown = () => setOpen((prev) => !prev);

    const handleChange = (lang) => {
        if (lang !== i18n.language) {
            i18n.changeLanguage(lang).catch(console.error);
        }
        setOpen(false);
    };

    useEffect(() => {
        const handleClickOutside = (event) => {
            if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
                setOpen(false);
            }
        };
        if (open) document.addEventListener("mousedown", handleClickOutside);
        return () => document.removeEventListener("mousedown", handleClickOutside);
    }, [open]);

    return (
        <div ref={dropdownRef} className="relative inline-block text-left z-20">
            <button
                onClick={toggleDropdown}
                aria-haspopup="true"
                aria-expanded={open}
                aria-label="Seleziona lingua"
                className="flex items-center gap-2 rounded bg-gray-200 px-3 py-1 text-sm font-medium text-gray-900
                          hover:ring-2 hover:ring-blue-400 focus:outline-none focus:ring-2 focus:ring-blue-500
                          dark:bg-gray-700 dark:text-white dark:hover:ring-blue-300 transition
                          min-w-[5.5rem] sm:min-w-[6.5rem]"
                type="button"
            >
                <img
                    src={flags[i18n.language]}
                    alt={`${i18n.language} flag`}
                    className="w-5 h-auto rounded-sm shadow"
                    loading="lazy"
                />
                <span className="uppercase select-none">{i18n.language}</span>
                <svg
                    className={`w-4 h-4 transition-transform ${open ? "rotate-180" : "rotate-0"}`}
                    fill="none"
                    stroke="currentColor"
                    strokeWidth="2"
                    viewBox="0 0 24 24"
                    aria-hidden="true"
                    xmlns="http://www.w3.org/2000/svg"
                >
                    <path strokeLinecap="round" strokeLinejoin="round" d="M19 9l-7 7-7-7"></path>
                </svg>
            </button>

            {open && (
                <div
                    className="absolute right-0 mt-2 w-full max-w-[12rem] sm:max-w-[16rem] origin-top-right
                                rounded-md bg-white shadow-lg ring-1 ring-black ring-opacity-5
                                focus:outline-none dark:bg-gray-800 animate-fade-in"
                    role="menu"
                    aria-label="Selezione lingua"
                    style={{zIndex: 9999}}
                >
                    {Object.entries(flags).map(([lang, flagUrl]) => (
                        <button
                            key={lang}
                            onClick={() => handleChange(lang)}
                            className={` flex w-full items-center gap-3 px-4 py-3 text-base
                                        text-gray-900 hover:bg-gray-100 focus:bg-gray-100
                                        dark:text-white dark:hover:bg-gray-700 dark:focus:bg-gray-700 transition-colors truncate
                                        ${lang === i18n.language ? "font-semibold bg-gray-200 dark:bg-gray-700 cursor-default" : "cursor-pointer"}
                                      `}
                            role="menuitem"
                            type="button"
                            disabled={lang === i18n.language}
                            aria-current={lang === i18n.language ? "true" : undefined}
                            style={{minHeight: 44}} // Touch target min 44px height
                        >
                            <img
                                src={flagUrl}
                                alt={`${lang} flag`}
                                className="w-6 h-auto rounded-sm shadow"
                                loading="lazy"
                            />
                            <div className="flex flex-col text-left">
                                <span className="text-sm font-semibold uppercase">{lang}</span>
                                <span className="text-xs text-gray-500 dark:text-gray-400">{languageLabels[lang]}</span>
                            </div>
                        </button>
                    ))}
                </div>
            )}
        </div>
    );
}