import React, { useState, useMemo, useRef, useEffect } from 'react'; import { X, Search, Globe, Plus } from 'lucide-react'; import { POPULAR_LANGS } from '../utils/constants'; import { LANG_CODES } from '../utils/languages'; import './MultiLangPicker.css'; /** * MultiLangPicker — chip-based multi-language selector for batch dubbing. * * Shows selected languages as removable badges. Click "+" to open a * searchable dropdown with Popular + All Languages sections. */ export default function MultiLangPicker({ selected = [], // array of { lang: string, code: string } onChange, // (newSelected) => void disabled = false, }) { const [dropOpen, setDropOpen] = useState(false); const [query, setQuery] = useState(''); const dropRef = useRef(null); const inputRef = useRef(null); // Close dropdown on outside click useEffect(() => { if (!dropOpen) return; const handler = (e) => { if (dropRef.current && !dropRef.current.contains(e.target)) setDropOpen(false); }; document.addEventListener('mousedown', handler); return () => document.removeEventListener('mousedown', handler); }, [dropOpen]); // Focus search when dropdown opens useEffect(() => { if (dropOpen && inputRef.current) inputRef.current.focus(); }, [dropOpen]); const selectedCodes = useMemo(() => new Set(selected.map(s => s.code)), [selected]); const addLang = (lang, code) => { if (selectedCodes.has(code)) return; onChange([...selected, { lang, code }]); setQuery(''); }; const removeLang = (code) => { onChange(selected.filter(s => s.code !== code)); }; const filteredLangs = useMemo(() => { const q = query.toLowerCase().trim(); return LANG_CODES.filter(lc => !selectedCodes.has(lc.code) && (!q || lc.label.toLowerCase().includes(q) || lc.code.toLowerCase().includes(q)) ); }, [query, selectedCodes]); const popularFiltered = useMemo(() => { const q = query.toLowerCase().trim(); return POPULAR_LANGS .map(lang => { const match = LANG_CODES.find(lc => lc.label.toLowerCase() === lang.toLowerCase()); return match ? { lang, code: match.code } : null; }) .filter(item => item && !selectedCodes.has(item.code) && (!q || item.lang.toLowerCase().includes(q) || item.code.includes(q))); }, [query, selectedCodes]); return (