Newer
Older
cortex-hub / ui / client-app / src / pages / SettingsPage.js
import React, { useState, useEffect, useRef } from 'react';
import {
    getUserConfig, updateUserConfig, exportUserConfig, importUserConfig,
    verifyProvider, getProviderModels, getAllProviders, getVoices,
    getAdminUsers, updateUserRole, getAdminGroups, createAdminGroup,
    updateAdminGroup, deleteAdminGroup, updateUserGroup
} from '../services/apiService';

const SettingsPage = () => {
    const [config, setConfig] = useState({ llm: {}, tts: {}, stt: {} });
    const [effective, setEffective] = useState({ llm: {}, tts: {}, stt: {} });
    const [loading, setLoading] = useState(true);
    const [saving, setSaving] = useState(false);
    const [message, setMessage] = useState({ type: '', text: '' });
    const [activeConfigTab, setActiveConfigTab] = useState('llm');
    const [activeAdminTab, setActiveAdminTab] = useState('groups');
    const [userSearch, setUserSearch] = useState('');
    const [expandedProvider, setExpandedProvider] = useState(null);
    const [selectedNewProvider, setSelectedNewProvider] = useState('');
    const [verifying, setVerifying] = useState(null);
    const [fetchedModels, setFetchedModels] = useState({});
    const [providerLists, setProviderLists] = useState({ llm: [], tts: [], stt: [] });
    const [providerStatuses, setProviderStatuses] = useState({});
    const [voiceList, setVoiceList] = useState([]);
    const [showVoicesModal, setShowVoicesModal] = useState(false);
    const [voicesLoading, setVoicesLoading] = useState(false);
    const [allUsers, setAllUsers] = useState([]);
    const [usersLoading, setUsersLoading] = useState(false);
    const [allGroups, setAllGroups] = useState([]);
    const [groupsLoading, setGroupsLoading] = useState(false);
    const [editingGroup, setEditingGroup] = useState(null);
    const [addingSection, setAddingSection] = useState(null);
    const [addForm, setAddForm] = useState({ type: '', suffix: '', model: '', cloneFrom: '' });
    const fileInputRef = useRef(null);

    const handleViewVoices = async (providerId, apiKey = null) => {
        setShowVoicesModal(true);
        setVoicesLoading(true);
        setVoiceList([]); // Clear previous list while loading
        try {
            const voices = await getVoices(providerId, apiKey);
            setVoiceList(voices);
        } catch (e) {
            console.error(e);
        } finally {
            setVoicesLoading(false);
        }
    };

    useEffect(() => {
        const fetchProviders = async () => {
            try {
                const [llm, tts, stt] = await Promise.all([
                    getAllProviders('llm'),
                    getAllProviders('tts'),
                    getAllProviders('stt')
                ]);
                setProviderLists({
                    llm: llm.map(id => ({ id, label: id === 'general' ? 'General (LiteLLM / Custom)' : id.charAt(0).toUpperCase() + id.slice(1) })).sort((a, b) => a.label.localeCompare(b.label)),
                    tts: tts.map(id => ({ id, label: id === 'general' ? 'General (LiteLLM / Custom)' : id.charAt(0).toUpperCase() + id.slice(1) })).sort((a, b) => a.label.localeCompare(b.label)),
                    stt: stt.map(id => ({ id, label: id === 'general' ? 'General (LiteLLM / Custom)' : (id === 'google_gemini' ? 'Google Gemini' : id.charAt(0).toUpperCase() + id.slice(1)) })).sort((a, b) => a.label.localeCompare(b.label))
                });
            } catch (e) {
                console.error("Failed to load provider lists", e);
            }
        };
        fetchProviders();
    }, []);

    useEffect(() => {
        loadConfig();
        loadUsers();
        loadGroups();
    }, []);

    const loadGroups = async () => {
        try {
            setGroupsLoading(true);
            const groups = await getAdminGroups();
            setAllGroups(groups);
        } catch (e) {
            console.error("Failed to load groups", e);
        } finally {
            setGroupsLoading(false);
        }
    };

    const loadUsers = async () => {
        try {
            setUsersLoading(true);
            const users = await getAdminUsers();
            setAllUsers(users);
        } catch (e) {
            console.error("Failed to load users", e);
        } finally {
            setUsersLoading(false);
        }
    };

    const handleRoleToggle = async (user) => {
        const newRole = user.role === 'admin' ? 'user' : 'admin';
        try {
            await updateUserRole(user.id, newRole);
            setMessage({ type: 'success', text: `Role for ${user.username || user.email} updated to ${newRole}` });
            loadUsers(); // refresh list
            setTimeout(() => setMessage({ type: '', text: '' }), 3000);
        } catch (e) {
            setMessage({ type: 'error', text: e.message || 'Failed to update role' });
        }
    };

    const handleGroupChange = async (targetUserId, groupId) => {
        try {
            await updateUserGroup(targetUserId, groupId);
            setMessage({ type: 'success', text: `User group updated successfully` });
            loadUsers();
            setTimeout(() => setMessage({ type: '', text: '' }), 3000);
        } catch (e) {
            setMessage({ type: 'error', text: e.message || 'Failed to update group' });
        }
    };

    const handleSaveGroup = async (e) => {
        e.preventDefault();
        try {
            setSaving(true);
            if (editingGroup.id === 'new') {
                const { id, ...data } = editingGroup;
                await createAdminGroup(data);
            } else {
                await updateAdminGroup(editingGroup.id, editingGroup);
            }
            setMessage({ type: 'success', text: 'Group saved successfully!' });
            setEditingGroup(null);
            loadGroups();
            loadUsers();
            setTimeout(() => setMessage({ type: '', text: '' }), 3000);
        } catch (e) {
            setMessage({ type: 'error', text: e.message || 'Failed to save group' });
        } finally {
            setSaving(false);
        }
    };

    const handleDeleteGroup = async (groupId) => {
        if (!window.confirm("Are you sure? Users in this group will be moved to 'Ungrouped'.")) return;
        try {
            await deleteAdminGroup(groupId);
            setMessage({ type: 'success', text: 'Group deleted' });
            loadGroups();
            loadUsers();
            setTimeout(() => setMessage({ type: '', text: '' }), 3000);
        } catch (e) {
            setMessage({ type: 'error', text: e.message || 'Failed to delete group' });
        }
    };

    const loadConfig = async () => {
        try {
            setLoading(true);
            const data = await getUserConfig();
            setConfig({
                llm: data.preferences?.llm || {},
                tts: data.preferences?.tts || {},
                stt: data.preferences?.stt || {}
            });
            setProviderStatuses(data.preferences?.statuses || {});
            setEffective(data.effective || { llm: {}, tts: {}, stt: {} });
            setMessage({ type: '', text: '' });
        } catch (err) {
            console.error("Error loading config:", err);
            setMessage({ type: 'error', text: 'Failed to load configuration.' });
        } finally {
            setLoading(false);
        }
    };

    useEffect(() => {
        if (expandedProvider) {
            const parts = expandedProvider.split('_');
            const sectionKey = parts[0];
            const providerId = parts.slice(1).join('_');

            const fetchKey = `${sectionKey}_${providerId}`;
            if (!fetchedModels[fetchKey]) {
                getProviderModels(providerId, sectionKey).then(models => {
                    setFetchedModels(prev => ({ ...prev, [fetchKey]: models }));
                }).catch(e => console.warn("Failed fetching models for", providerId, "section", sectionKey));
            }
        }
    }, [expandedProvider, fetchedModels]);

    // Pre-fetch model list for the selected type in the add-new-instance form
    useEffect(() => {
        if (addingSection && addForm.type) {
            const fetchKey = `${addingSection}_${addForm.type}`;
            if (!fetchedModels[fetchKey]) {
                getProviderModels(addForm.type, addingSection).then(models => {
                    setFetchedModels(prev => ({ ...prev, [fetchKey]: models }));
                }).catch(() => { });
            }
        }
    }, [addingSection, addForm.type, fetchedModels]);

    const handleSave = async (e) => {
        e.preventDefault();
        try {
            setSaving(true);
            setMessage({ type: '', text: 'Saving and verifying configuration...' });

            // Before saving, let's identify any "active" providers that have been modified 
            // (i.e. they are grey/have no status) and run a quick verification for them.
            const updatedStatuses = { ...providerStatuses };
            const sections = ['llm', 'tts', 'stt'];

            for (const section of sections) {
                const activeId = config[section]?.active_provider;
                if (activeId && !updatedStatuses[`${section}_${activeId}`]) {
                    const providerPrefs = config[section]?.providers?.[activeId];
                    if (providerPrefs && providerPrefs.api_key) {
                        try {
                            const res = await verifyProvider(section, {
                                provider_name: activeId,
                                provider_type: providerPrefs.provider_type || activeId.split('_')[0],
                                api_key: providerPrefs.api_key,
                                model: providerPrefs.model,
                                voice: providerPrefs.voice
                            });
                            updatedStatuses[`${section}_${activeId}`] = res.success ? 'success' : 'error';
                        } catch (err) {
                            updatedStatuses[`${section}_${activeId}`] = 'error';
                        }
                    }
                }
            }

            setProviderStatuses(updatedStatuses);
            const payload = { ...config, statuses: updatedStatuses };
            await updateUserConfig(payload);

            // reload after save to get latest effective config
            await loadConfig();
            setMessage({ type: 'success', text: 'Settings saved and verified successfully!' });
            setTimeout(() => setMessage({ type: '', text: '' }), 3000);
        } catch (err) {
            console.error("Error saving config:", err);
            setMessage({ type: 'error', text: 'Failed to save configuration: ' + (err.message || "Unknown error") });
        } finally {
            setSaving(false);
        }
    };

    const handleExport = async () => {
        try {
            const response = await exportUserConfig();
            const blob = await response.blob();
            const url = window.URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.href = url;
            a.download = "config.yaml";
            document.body.appendChild(a);
            a.click();
            window.URL.revokeObjectURL(url);
            document.body.removeChild(a);
        } catch (error) {
            console.error("Export Error: ", error);
            setMessage({ type: 'error', text: 'Failed to export YAML.' });
        }
    };

    const handleGrantToAll = async (section, providerId) => {
        if (!window.confirm(`Are you sure? This will whitelist ${providerId} for ALL existing groups.`)) return;
        try {
            setSaving(true);
            setMessage({ type: '', text: `Syncing group policies for ${providerId}...` });
            for (const group of allGroups) {
                const currentPolicy = group.policy || { llm: [], tts: [], stt: [] };
                const sectionList = currentPolicy[section] || [];
                if (!sectionList.includes(providerId)) {
                    const newPolicy = { ...currentPolicy, [section]: [...sectionList, providerId] };
                    await updateAdminGroup(group.id, { ...group, policy: newPolicy });
                }
            }
            await loadGroups();
            setMessage({ type: 'success', text: `Global access granted for ${providerId}!` });
            setTimeout(() => setMessage({ type: '', text: '' }), 3000);
        } catch (e) {
            console.error(e);
            setMessage({ type: 'error', text: 'Failed to sync group access.' });
        } finally {
            setSaving(false);
        }
    };

    const handleImport = async (e) => {
        const file = e.target.files[0];
        if (!file) return;
        try {
            setLoading(true);
            const formData = new FormData();
            formData.append('file', file);
            await importUserConfig(formData);
            await loadConfig();
            setMessage({ type: 'success', text: 'Configuration imported successfully!' });
            setTimeout(() => setMessage({ type: '', text: '' }), 3000);
        } catch (error) {
            console.error("Import Error: ", error);
            setMessage({ type: 'error', text: 'Failed to import YAML: ' + error.message });
        } finally {
            setLoading(false);
            if (fileInputRef.current) fileInputRef.current.value = '';
        }
    };

    const handleChange = (section, field, value, providerId = null) => {
        if (field === 'providers' && providerId) {
            setProviderStatuses(prev => {
                const updated = { ...prev };
                delete updated[`${section}_${providerId}`];
                return updated;
            });
        }
        setConfig((prev) => ({
            ...prev,
            [section]: {
                ...prev[section],
                [field]: value
            }
        }));
    };

    if (loading) {
        return (
            <div className="flex h-screen items-center justify-center dark:bg-gray-900">
                <div className="text-xl text-gray-400 animate-pulse">Loading settings...</div>
            </div>
        );
    }

    const inputClass = "w-full border border-gray-300 dark:border-gray-600 rounded-lg p-3 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 placeholder-gray-400 dark:placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 transition-colors duration-200 shadow-sm";
    const labelClass = "block text-sm font-semibold text-gray-700 dark:text-gray-300 mb-2";
    const sectionClass = "animate-fade-in";

    const renderProviderSection = (sectionKey, providerDefs, allowVoice = false) => {
        const activeProviderIds = new Set([
            ...Object.keys(config[sectionKey]?.providers || {}),
            ...Object.keys(effective[sectionKey]?.providers || {})
        ]);
        const activeProviders = Array.from(activeProviderIds).map(id => {
            const baseP = providerDefs.find(p => p.id === id);
            if (baseP) return baseP;
            // Handle suffixed IDs (e.g. gemini_2)
            const parts = id.split('_');
            let baseId = parts[0];
            // Special case for google_gemini
            if (id.startsWith('google_gemini_')) baseId = 'google_gemini';

            const baseDef = providerDefs.find(p => p.id === baseId);
            const suffix = id.replace(baseId + '_', '');
            return {
                id: id,
                label: baseDef ? `${baseDef.label} (${suffix})` : id
            };
        }).sort((a, b) => a.label.localeCompare(b.label));

        const currentActivePrimary = config[sectionKey]?.active_provider || effective[sectionKey]?.active_provider || '';

        const handleAddInstance = () => {
            if (!addForm.type) return;
            const newId = addForm.suffix ? `${addForm.type}_${addForm.suffix.toLowerCase().replace(/\s+/g, '_')}` : addForm.type;

            if (activeProviderIds.has(newId)) {
                setMessage({ type: 'error', text: `Instance "${newId}" already exists.` });
                return;
            }

            // Build initial provider data
            const initData = { provider_type: addForm.type };

            // Store a _clone_from marker — the backend will resolve the real API key
            // from the source provider. We never have the plaintext key on the frontend.
            if (addForm.cloneFrom) {
                initData._clone_from = addForm.cloneFrom;
            }

            // Pre-set model if specified
            if (addForm.model.trim()) initData.model = addForm.model.trim();

            const newProviders = { ...(config[sectionKey]?.providers || {}) };
            newProviders[newId] = initData;
            handleChange(sectionKey, 'providers', newProviders, newId);
            setAddingSection(null);
            setAddForm({ type: '', suffix: '', model: '', cloneFrom: '' });
            setExpandedProvider(`${sectionKey}_${newId}`);
        };

        // Existing instances of the same type that have an API key — for cloning
        const cloneableSources = Array.from(activeProviderIds).filter(id => {
            const baseType = id.startsWith('google_gemini') ? 'google_gemini' : id.split('_')[0];
            return baseType === addForm.type && id !== addForm.type + (addForm.suffix ? '_' + addForm.suffix.toLowerCase().replace(/\s+/g, '_') : '');
        });

        const handleDeleteProvider = (providerId) => {
            const newProviders = { ...((config[sectionKey] && config[sectionKey].providers) || {}) };
            delete newProviders[providerId];
            handleChange(sectionKey, 'providers', newProviders, providerId);
            if (currentActivePrimary === providerId) {
                handleChange(sectionKey, 'active_provider', Object.keys(newProviders)[0] || '');
            }
            if (expandedProvider === `${sectionKey}_${providerId}`) setExpandedProvider(null);
        };

        const handleSetActive = async (providerId) => {
            // Update local state immediately for responsive UI
            handleChange(sectionKey, 'active_provider', providerId);
            // Persist immediately to DB so it survives refresh
            try {
                const newConfig = {
                    ...config,
                    [sectionKey]: {
                        ...config[sectionKey],
                        active_provider: providerId
                    }
                };
                await updateUserConfig(newConfig);
                setMessage({ type: 'success', text: `${sectionKey.toUpperCase()} primary provider set to "${providerId}"` });
                setTimeout(() => setMessage({ type: '', text: '' }), 2000);
            } catch (e) {
                console.error('Failed to persist active_provider', e);
            }
        };

        const handleVerifyProvider = async (providerId, providerPrefs) => {
            try {
                setVerifying(`${sectionKey}_${providerId}`);
                setMessage({ type: '', text: '' });
                const payload = {
                    provider_name: providerId,
                    provider_type: providerPrefs.provider_type || providerId.split('_')[0],
                    api_key: providerPrefs.api_key,
                    model: providerPrefs.model,
                    voice: providerPrefs.voice
                };
                const res = await verifyProvider(sectionKey, payload);
                if (res.success) {
                    const newStatuses = { ...providerStatuses, [`${sectionKey}_${providerId}`]: 'success' };
                    setProviderStatuses(newStatuses);
                    await updateUserConfig({ ...config, statuses: newStatuses });
                    setMessage({ type: 'success', text: `Verified ${providerId} successfully!` });
                } else {
                    const newStatuses = { ...providerStatuses, [`${sectionKey}_${providerId}`]: 'error' };
                    setProviderStatuses(newStatuses);
                    await updateUserConfig({ ...config, statuses: newStatuses });
                    setMessage({ type: 'error', text: `Verification failed for ${providerId}: ${res.message}` });
                }
            } catch (err) {
                setMessage({ type: 'error', text: `Error verifying ${providerId}.` });
            } finally {
                setVerifying(null);
                setTimeout(() => setMessage({ type: '', text: '' }), 5000);
            }
        };

        return (
            <div className="space-y-6">
                {/* Header & Add Form */}
                <div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4 border-b border-gray-100 dark:border-gray-700 pb-4">
                    <div className="flex items-center gap-3">
                        <div className="p-2 bg-indigo-50 dark:bg-indigo-900/30 rounded-lg text-indigo-600 dark:text-indigo-400">
                            <svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" /></svg>
                        </div>
                        <div>
                            <h3 className="text-sm font-black text-gray-900 dark:text-white uppercase tracking-wider">Resource Instances</h3>
                            <p className="text-[10px] text-gray-500 dark:text-gray-400 font-medium">Configure specific account credentials</p>
                        </div>
                    </div>

                    {addingSection !== sectionKey ? (
                        <button
                            type="button"
                            onClick={() => { setAddingSection(sectionKey); setAddForm({ type: '', suffix: '', model: '', cloneFrom: '' }); }}
                            className="px-4 py-2 bg-indigo-600 hover:bg-indigo-700 text-white text-[10px] font-black uppercase tracking-widest rounded-lg shadow-md transition-all flex items-center gap-2"
                        >
                            <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2.5} d="M12 6v6m0 0v6m0-6h6m-6 0H6" /></svg>
                            Register New Instance
                        </button>
                    ) : (
                        <div className="w-full mt-2 bg-white dark:bg-gray-800 border border-indigo-200 dark:border-indigo-700 rounded-2xl shadow-lg p-4 animate-in fade-in slide-in-from-top-2 duration-200 space-y-3">
                            <p className="text-[10px] font-black uppercase tracking-widest text-indigo-500 mb-1">New Provider Instance</p>

                            {/* Row 1: Type + Label suffix */}
                            <div className="flex flex-col sm:flex-row gap-3">
                                <div className="flex-1">
                                    <label className="block text-[9px] font-black text-gray-400 uppercase tracking-widest mb-1">Provider Type</label>
                                    <select
                                        value={addForm.type}
                                        onChange={(e) => setAddForm({ type: e.target.value, suffix: '', model: '', cloneFrom: '' })}
                                        className="w-full border border-gray-200 dark:border-gray-700 rounded-lg px-3 py-2 bg-white dark:bg-gray-900 text-sm font-bold text-gray-800 dark:text-gray-100 focus:ring-2 focus:ring-indigo-500 outline-none"
                                    >
                                        <option value="">Select type…</option>
                                        {providerDefs.map(p => (
                                            <option key={p.id} value={p.id}>{p.label}</option>
                                        ))}
                                    </select>
                                </div>
                                <div className="flex-1">
                                    <label className="block text-[9px] font-black text-gray-400 uppercase tracking-widest mb-1">
                                        Label Suffix <span className="normal-case font-normal text-gray-400">(e.g. flash25, 3pro)</span>
                                    </label>
                                    <input
                                        placeholder="e.g. flash25"
                                        value={addForm.suffix}
                                        onChange={(e) => setAddForm({ ...addForm, suffix: e.target.value })}
                                        className="w-full border border-gray-200 dark:border-gray-700 rounded-lg px-3 py-2 bg-white dark:bg-gray-900 text-sm text-gray-800 dark:text-gray-100 focus:ring-2 focus:ring-indigo-500 outline-none"
                                    />
                                    {addForm.type && addForm.suffix && (
                                        <p className="mt-1 text-[9px] text-gray-400">
                                            ID: <span className="font-mono text-indigo-500">{addForm.type}_{addForm.suffix.toLowerCase().replace(/\s+/g, '_')}</span>
                                        </p>
                                    )}
                                </div>
                            </div>

                            {/* Row 2: Model + Clone-from */}
                            <div className="flex flex-col sm:flex-row gap-3">
                                <div className="flex-1">
                                    <label className="block text-[9px] font-black text-gray-400 uppercase tracking-widest mb-1">
                                        Pre-set Model <span className="normal-case font-normal text-gray-400">(users will see this)</span>
                                    </label>
                                    {addForm.type && fetchedModels[`${sectionKey}_${addForm.type}`]?.length > 0 ? (
                                        <select
                                            value={addForm.model}
                                            onChange={(e) => setAddForm({ ...addForm, model: e.target.value })}
                                            className="w-full border border-gray-200 dark:border-gray-700 rounded-lg px-3 py-2 bg-white dark:bg-gray-900 text-sm text-gray-800 dark:text-gray-100 focus:ring-2 focus:ring-indigo-500 outline-none"
                                        >
                                            <option value="">-- Choose model --</option>
                                            {fetchedModels[`${sectionKey}_${addForm.type}`].map(m => (
                                                <option key={m.model_name} value={m.model_name}>
                                                    {m.model_name}{m.max_input_tokens ? ` (${Math.round(m.max_input_tokens / 1000)}k ctx)` : ''}
                                                </option>
                                            ))}
                                        </select>
                                    ) : (
                                        <input
                                            placeholder="e.g. gemini-2.5-flash-preview"
                                            value={addForm.model}
                                            onChange={(e) => setAddForm({ ...addForm, model: e.target.value })}
                                            className="w-full border border-gray-200 dark:border-gray-700 rounded-lg px-3 py-2 bg-white dark:bg-gray-900 text-sm text-gray-800 dark:text-gray-100 focus:ring-2 focus:ring-indigo-500 outline-none"
                                        />
                                    )}
                                </div>
                                {cloneableSources.length > 0 && (
                                    <div className="flex-1">
                                        <label className="block text-[9px] font-black text-gray-400 uppercase tracking-widest mb-1">
                                            Inherit API Key From <span className="normal-case font-normal text-gray-400">(reuse existing key)</span>
                                        </label>
                                        <select
                                            value={addForm.cloneFrom}
                                            onChange={(e) => setAddForm({ ...addForm, cloneFrom: e.target.value })}
                                            className="w-full border border-gray-200 dark:border-gray-700 rounded-lg px-3 py-2 bg-white dark:bg-gray-900 text-sm text-gray-800 dark:text-gray-100 focus:ring-2 focus:ring-indigo-500 outline-none"
                                        >
                                            <option value="">-- Enter key manually --</option>
                                            {cloneableSources.map(id => (
                                                <option key={id} value={id}>{id}</option>
                                            ))}
                                        </select>
                                        {addForm.cloneFrom && (
                                            <p className="mt-1 text-[9px] text-emerald-500 font-bold">✓ API key will be copied from "{addForm.cloneFrom}" on save</p>
                                        )}
                                    </div>
                                )}
                            </div>

                            {/* Action buttons */}
                            <div className="flex justify-end gap-2 pt-1">
                                <button
                                    type="button"
                                    onClick={() => { setAddingSection(null); setAddForm({ type: '', suffix: '', model: '', cloneFrom: '' }); }}
                                    className="px-4 py-2 bg-gray-100 dark:bg-gray-700 text-gray-600 dark:text-gray-300 rounded-lg text-sm font-semibold hover:bg-gray-200 dark:hover:bg-gray-600 transition-colors"
                                >
                                    Cancel
                                </button>
                                <button
                                    type="button"
                                    onClick={handleAddInstance}
                                    disabled={!addForm.type}
                                    className="px-4 py-2 bg-indigo-600 hover:bg-indigo-700 disabled:opacity-40 text-white rounded-lg text-sm font-black tracking-wide transition-colors flex items-center gap-2"
                                >
                                    <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2.5} d="M5 13l4 4L19 7" /></svg>
                                    Add Instance
                                </button>
                            </div>
                        </div>
                    )}
                </div>

                <div className="flex gap-6 items-center px-4 py-3 bg-gray-50 dark:bg-gray-800/40 rounded-xl border border-dashed border-gray-200 dark:border-gray-700">
                    <span className="text-[10px] font-black uppercase tracking-widest text-gray-400">Status Legend:</span>
                    <div className="flex items-center gap-2">
                        <div className="w-2 h-2 rounded-full bg-emerald-500"></div>
                        <span className="text-[11px] font-bold text-gray-500 dark:text-gray-400">Verified</span>
                    </div>
                    <div className="flex items-center gap-2">
                        <div className="w-2 h-2 rounded-full bg-red-500"></div>
                        <span className="text-[11px] font-bold text-gray-500 dark:text-gray-400">Failed</span>
                    </div>
                    <div className="flex items-center gap-2">
                        <div className="w-2 h-2 rounded-full bg-gray-300"></div>
                        <span className="text-[11px] font-bold text-gray-500 dark:text-gray-400">Not Tested</span>
                    </div>
                </div>

                <div className="space-y-4">
                    {activeProviders.length === 0 && (
                        <p className="text-gray-500 text-sm text-center py-4">No providers enabled. Add one above.</p>
                    )}
                    {activeProviders.map((provider) => {
                        const isExpanded = expandedProvider === `${sectionKey}_${provider.id}`;
                        const providerPrefs = config[sectionKey]?.providers?.[provider.id] || {};
                        const providerEff = effective[sectionKey]?.providers?.[provider.id] || {};
                        const isActivePrimary = currentActivePrimary === provider.id;

                        return (
                            <div key={provider.id} className={`border ${isActivePrimary ? 'border-indigo-400 dark:border-indigo-600' : 'border-gray-200 dark:border-gray-700'} rounded-lg overflow-hidden bg-white dark:bg-gray-800 shadow-sm transition-all duration-200`}>
                                <div
                                    onClick={() => setExpandedProvider(isExpanded ? null : `${sectionKey}_${provider.id}`)}
                                    className="flex justify-between items-center p-4 cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-700/50"
                                >
                                    <h3 className="font-bold text-gray-900 dark:text-gray-100 flex items-center gap-2 max-w-[150px] sm:max-w-xs truncate">
                                        <div className={`w-2 h-2 rounded-full flex-shrink-0 ${providerStatuses[`${sectionKey}_${provider.id}`] === 'success' ? 'bg-emerald-500' : providerStatuses[`${sectionKey}_${provider.id}`] === 'error' ? 'bg-red-500' : 'bg-gray-300'}`}></div>
                                        <span className="truncate">{provider.label}</span>
                                        {isActivePrimary && (
                                            <span className="ml-2 px-2 py-0.5 text-[10px] font-bold uppercase tracking-wider text-indigo-700 bg-indigo-100 dark:text-indigo-300 dark:bg-indigo-900/50 rounded-full flex-shrink-0">Primary</span>
                                        )}
                                    </h3>
                                    <div className="flex items-center gap-2 sm:gap-4 flex-1 justify-end overflow-hidden">
                                        <div className="text-[10px] font-black uppercase tracking-widest text-gray-500 hidden sm:block truncate max-w-[160px]">
                                            {providerPrefs._clone_from ? (
                                                <span className="inline-flex items-center gap-1 text-amber-600 dark:text-amber-400">
                                                    <svg className="w-3 h-3 flex-shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2.5} d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" /></svg>
                                                    <span className="truncate">Key from {providerPrefs._clone_from}</span>
                                                </span>
                                            ) : (providerPrefs.model || providerEff.model) ? (
                                                <span className="font-mono normal-case tracking-normal text-gray-400 truncate">
                                                    {providerPrefs.model || providerEff.model}
                                                </span>
                                            ) : null}
                                        </div>
                                        {!isActivePrimary && (
                                            <button
                                                type="button"
                                                onClick={(e) => {
                                                    e.stopPropagation();
                                                    handleSetActive(provider.id);
                                                }}
                                                className="text-[11px] uppercase tracking-wider text-indigo-700 bg-indigo-50 hover:bg-indigo-100 dark:bg-indigo-900/40 dark:hover:bg-indigo-900/60 dark:text-indigo-300 font-bold px-2 py-1.5 rounded transition-colors shadow-sm border border-indigo-200 dark:border-indigo-800/50"
                                            >
                                                Set Primary
                                            </button>
                                        )}
                                        <button
                                            type="button"
                                            disabled={saving}
                                            onClick={(e) => {
                                                e.stopPropagation();
                                                handleGrantToAll(sectionKey, provider.id);
                                            }}
                                            className="text-[10px] font-black uppercase tracking-widest text-indigo-600 bg-indigo-50 hover:bg-indigo-100 dark:bg-indigo-900/30 dark:hover:bg-indigo-900/50 dark:text-indigo-400 px-2 py-1.5 rounded transition-all border border-indigo-100 dark:border-indigo-800/50"
                                            title="Add this provider to ALL group whitelists"
                                        >
                                            Grant All Groups
                                        </button>
                                        <button
                                            type="button"
                                            onClick={(e) => {
                                                e.stopPropagation();
                                                handleDeleteProvider(provider.id);
                                            }}
                                            className="text-[10px] font-black uppercase tracking-widest text-red-600 bg-red-50 hover:bg-red-100 dark:bg-red-900/30 dark:hover:bg-red-900/50 dark:text-red-400 px-2 py-1.5 rounded transition-all border border-red-100 dark:border-red-800/50"
                                        >
                                            Remove
                                        </button>
                                        <button
                                            type="button"
                                            disabled={verifying === `${sectionKey}_${provider.id}`}
                                            onClick={(e) => {
                                                e.stopPropagation();
                                                handleVerifyProvider(provider.id, providerPrefs);
                                            }}
                                            className="text-xs text-emerald-700 bg-emerald-50 hover:bg-emerald-100 dark:bg-emerald-900/40 dark:hover:bg-emerald-900/60 dark:text-emerald-300 font-semibold px-2 py-1 rounded transition-colors"
                                        >
                                            {verifying === `${sectionKey}_${provider.id}` ? 'Testing...' : 'Test'}
                                        </button>
                                        <svg className={`w-5 h-5 flex-shrink-0 text-gray-500 transform transition-transform ${isExpanded ? 'rotate-180' : ''}`} fill="none" viewBox="0 0 24 24" stroke="currentColor">
                                            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
                                        </svg>
                                    </div>
                                </div>
                                {isExpanded && (
                                    <div className="p-4 border-t border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-800/50">
                                        <div className="mb-4 flex gap-4">
                                            <div className="flex-1">
                                                <div className="flex items-center justify-between mb-2">
                                                    <label className={labelClass} style={{ margin: 0 }}>API Key</label>
                                                    {providerPrefs._clone_from && (
                                                        <button
                                                            type="button"
                                                            title="Unlink from source and enter a new key manually"
                                                            onClick={() => {
                                                                const newProviders = { ...(config[sectionKey]?.providers || {}) };
                                                                const { _clone_from, ...rest } = providerPrefs;
                                                                newProviders[provider.id] = { ...rest, api_key: '' };
                                                                handleChange(sectionKey, 'providers', newProviders, provider.id);
                                                            }}
                                                            className="text-[9px] font-black uppercase tracking-widest flex items-center gap-1 text-amber-600 hover:text-amber-800 dark:text-amber-400 dark:hover:text-amber-200 transition-colors"
                                                        >
                                                            <svg className="w-3 h-3" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2.5} d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" /></svg>
                                                            Unlink
                                                        </button>
                                                    )}
                                                </div>
                                                {providerPrefs._clone_from ? (
                                                    <div className="relative">
                                                        <div className="flex items-center gap-2 w-full border border-amber-200 dark:border-amber-800/60 rounded-lg p-3 bg-amber-50/60 dark:bg-amber-900/10 cursor-not-allowed">
                                                            <svg className="w-4 h-4 flex-shrink-0 text-amber-500" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2.5} d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" /></svg>
                                                            <span className="text-sm text-amber-700 dark:text-amber-300 font-medium">Inherited from &ldquo;{providerPrefs._clone_from}&rdquo;</span>
                                                            <span className="ml-auto text-[10px] font-black uppercase tracking-widest text-amber-500 bg-amber-100 dark:bg-amber-900/40 px-2 py-0.5 rounded-full">Linked</span>
                                                        </div>
                                                        <p className="mt-1.5 text-[10px] text-amber-600 dark:text-amber-400 font-medium">
                                                            API key is managed by &ldquo;{providerPrefs._clone_from}&rdquo;. Click <strong>Unlink</strong> above to set an independent key.
                                                        </p>
                                                    </div>
                                                ) : (
                                                    <>
                                                        <input
                                                            type={providerPrefs.api_key?.includes('***') ? 'text' : 'password'}
                                                            value={providerPrefs.api_key || ''}
                                                            onChange={(e) => {
                                                                const newProviders = { ...(config[sectionKey]?.providers || {}) };
                                                                newProviders[provider.id] = { ...providerPrefs, api_key: e.target.value };
                                                                handleChange(sectionKey, 'providers', newProviders, provider.id);
                                                            }}
                                                            onFocus={(e) => {
                                                                if (e.target.value.includes('***')) {
                                                                    const newProviders = { ...(config[sectionKey]?.providers || {}) };
                                                                    newProviders[provider.id] = { ...providerPrefs, api_key: '' };
                                                                    handleChange(sectionKey, 'providers', newProviders, provider.id);
                                                                }
                                                            }}
                                                            placeholder="sk-..."
                                                            className={inputClass}
                                                        />
                                                        <p className="mt-2 text-xs text-gray-500 dark:text-gray-400">Specify your API key for {provider.label}.</p>
                                                    </>
                                                )}
                                            </div>
                                        </div>
                                        {!(sectionKey === 'tts' && provider.id === 'gcloud_tts') && (
                                            <div className="mb-4">
                                                <label className={labelClass}>Model Selection</label>
                                                {fetchedModels[`${sectionKey}_${provider.id}`] && fetchedModels[`${sectionKey}_${provider.id}`].length > 0 ? (
                                                    <select
                                                        value={providerPrefs.model || ''}
                                                        onChange={(e) => {
                                                            const newProviders = { ...(config[sectionKey]?.providers || {}) };
                                                            newProviders[provider.id] = { ...providerPrefs, model: e.target.value };
                                                            handleChange(sectionKey, 'providers', newProviders, provider.id);
                                                        }}
                                                        className={inputClass}
                                                    >
                                                        <option value="">-- Let Backend Decide Default --</option>
                                                        {fetchedModels[`${sectionKey}_${provider.id}`].map(m => (
                                                            <option key={m.model_name} value={m.model_name}>
                                                                {m.model_name} {m.max_input_tokens ? `(Context: ${Math.round(m.max_input_tokens / 1000)}k)` : ''}
                                                            </option>
                                                        ))}
                                                    </select>
                                                ) : (
                                                    <input
                                                        type="text"
                                                        value={providerPrefs.model || ''}
                                                        onChange={(e) => {
                                                            const newProviders = { ...(config[sectionKey]?.providers || {}) };
                                                            newProviders[provider.id] = { ...providerPrefs, model: e.target.value };
                                                            handleChange(sectionKey, 'providers', newProviders, provider.id);
                                                        }}
                                                        placeholder={provider.id === 'general' ? "E.g. vertex_ai/gemini-1.5-flash" : (sectionKey === 'llm' ? "E.g. gpt-4, claude-3-opus" : "E.g. whisper-1, gemini-1.5-flash")}
                                                        className={inputClass}
                                                    />
                                                )}
                                                <p className="mt-2 text-xs text-gray-500 dark:text-gray-400">
                                                    Specify exactly which model to pass to the provider API. Active default: <span className="font-mono text-gray-700 dark:text-gray-300">{providerEff.model || 'None'}</span>
                                                </p>
                                            </div>
                                        )}

                                        {allowVoice && (
                                            <div className="mb-4">
                                                <div className="flex items-center justify-between mb-2">
                                                    <label className={labelClass} style={{ margin: 0 }}>Voice Name</label>
                                                    <button type="button" onClick={() => handleViewVoices(provider.id, providerPrefs.api_key)} className="flex items-center justify-center w-5 h-5 rounded-full bg-blue-100 dark:bg-blue-900/60 text-blue-600 dark:text-blue-400 text-xs font-bold hover:bg-blue-200 dark:hover:bg-blue-800 transition-colors shadow-sm" title="View available voices">?</button>
                                                </div>
                                                <input
                                                    type="text"
                                                    value={providerPrefs.voice || ''}
                                                    onChange={(e) => {
                                                        const newProviders = { ...(config[sectionKey]?.providers || {}) };
                                                        newProviders[provider.id] = { ...providerPrefs, voice: e.target.value };
                                                        handleChange(sectionKey, 'providers', newProviders, provider.id);
                                                    }}
                                                    placeholder="E.g., Kore, en-US-Journey-F"
                                                    className={inputClass}
                                                />
                                                <p className="mt-2 text-xs text-gray-500 dark:text-gray-400">
                                                    Active default: <span className="font-mono text-gray-700 dark:text-gray-300">{providerEff.voice || 'None'}</span>
                                                </p>
                                            </div>
                                        )}

                                        {/* Custom Parameters Section */}
                                        <div className="mt-4 pt-4 border-t border-gray-100 dark:border-gray-700">
                                            <label className={`${labelClass} flex items-center gap-2`}>
                                                Custom Parameters
                                                <span className="text-[10px] font-normal normal-case text-gray-400">(e.g., vertex_project, vertex_location)</span>
                                            </label>

                                            <div className="space-y-2 mb-3">
                                                {Object.entries(providerPrefs).map(([key, value]) => {
                                                    // Filter out standard fields to only show "custom" ones here
                                                    if (['api_key', 'model', 'voice'].includes(key)) return null;
                                                    return (
                                                        <div key={key} className="flex gap-2 items-center animate-in fade-in slide-in-from-left-2 duration-200">
                                                            <div className="flex-1 bg-gray-50 dark:bg-gray-800/50 p-2 rounded-lg border border-gray-100 dark:border-gray-700 font-mono text-sm flex justify-between items-center group">
                                                                <span className="text-indigo-600 dark:text-indigo-400 font-bold">{key}:</span>
                                                                <span className="truncate ml-2 text-gray-600 dark:text-gray-300">{value}</span>
                                                            </div>
                                                            <button
                                                                type="button"
                                                                onClick={() => {
                                                                    const { [key]: deleted, ...rest } = providerPrefs;
                                                                    const newProviders = { ...(config[sectionKey]?.providers || {}) };
                                                                    newProviders[provider.id] = rest;
                                                                    handleChange(sectionKey, 'providers', newProviders, provider.id);
                                                                }}
                                                                className="p-2 text-red-500 hover:bg-red-50 dark:hover:bg-red-900/20 rounded-lg transition-colors"
                                                            >
                                                                <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" /></svg>
                                                            </button>
                                                        </div>
                                                    );
                                                })}
                                            </div>

                                            <div className="flex flex-col sm:flex-row gap-3">
                                                <div className="flex-[2] min-w-0 sm:min-w-[150px]">
                                                    <input
                                                        id={`new-key-${sectionKey}-${provider.id}`}
                                                        placeholder="Key (e.g. project_id)"
                                                        className={`${inputClass} !py-3 !text-sm w-full`}
                                                    />
                                                </div>
                                                <div className="flex-[3] min-w-0 sm:min-w-[200px]">
                                                    <input
                                                        id={`new-val-${sectionKey}-${provider.id}`}
                                                        placeholder="Value"
                                                        className={`${inputClass} !py-3 !text-sm w-full`}
                                                    />
                                                </div>
                                                <button
                                                    type="button"
                                                    onClick={() => {
                                                        const k = document.getElementById(`new-key-${sectionKey}-${provider.id}`).value.trim();
                                                        const v = document.getElementById(`new-val-${sectionKey}-${provider.id}`).value.trim();
                                                        if (k && v) {
                                                            const newProviders = { ...(config[sectionKey]?.providers || {}) };
                                                            newProviders[provider.id] = { ...providerPrefs, [k]: v };
                                                            handleChange(sectionKey, 'providers', newProviders, provider.id);
                                                            document.getElementById(`new-key-${sectionKey}-${provider.id}`).value = '';
                                                            document.getElementById(`new-val-${sectionKey}-${provider.id}`).value = '';
                                                        }
                                                    }}
                                                    className="px-6 py-3 bg-indigo-50 dark:bg-indigo-900/40 text-indigo-700 dark:text-indigo-300 rounded-xl text-sm font-bold hover:bg-indigo-100 dark:hover:bg-indigo-900/60 transition-all shadow-sm border border-indigo-200 dark:border-indigo-800/50 flex-shrink-0"
                                                >
                                                    Add Parameter
                                                </button>
                                            </div>
                                        </div>
                                    </div>
                                )}
                            </div>
                        );
                    })}
                </div>
            </div>
        );
    };

    const filteredUsers = allUsers.filter(u =>
        (u.username || '').toLowerCase().includes(userSearch.toLowerCase()) ||
        (u.email || '').toLowerCase().includes(userSearch.toLowerCase()) ||
        (u.full_name || '').toLowerCase().includes(userSearch.toLowerCase())
    );

    const sortedGroups = [...allGroups].sort((a, b) => {
        if (a.id === 'ungrouped') return -1;
        if (b.id === 'ungrouped') return 1;
        return a.name.localeCompare(b.name);
    });

    return (
        <div className="min-h-screen bg-gray-50 dark:bg-gray-900 pt-20 px-4 sm:px-6 lg:px-8 font-sans">
            <div className="max-w-3xl mx-auto">
                <div className="flex justify-between items-end mb-2">
                    <h1 className="text-3xl font-extrabold text-gray-900 dark:text-white tracking-tight">Configuration</h1>
                    <div className="flex gap-2">
                        <input
                            type="file"
                            ref={fileInputRef}
                            style={{ display: 'none' }}
                            accept=".yaml,.yml"
                            onChange={handleImport}
                        />
                        <button
                            type="button"
                            onClick={() => fileInputRef.current?.click()}
                            className="text-sm font-semibold px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800 text-gray-700 dark:text-gray-300 transition-colors shadow-sm flex items-center gap-2"
                        >
                            <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M4 16v1a2 2 0 002 2h12a2 2 0 002-2v-1m-4-8l-4-4m0 0L8 8m4-4v12" /></svg>
                            Import
                        </button>
                        <button
                            type="button"
                            onClick={handleExport}
                            className="text-sm font-semibold px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800 text-gray-700 dark:text-gray-300 transition-colors shadow-sm flex items-center gap-2"
                        >
                            <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M4 16v1a2 2 0 002 2h12a2 2 0 002-2v-1m-4-4l-4 4m0 0l-4-4m4 4V4" /></svg>
                            Export
                        </button>
                    </div>
                </div>
                <p className="text-gray-600 dark:text-gray-400 mb-8">
                    Customize your AI models, backend API tokens, and providers. These settings override system defaults.
                </p>

                {message.text && (
                    <div className={`p-4 rounded-xl mb-6 shadow-sm border ${message.type === 'error' ? 'bg-red-50 dark:bg-red-900/30 text-red-700 dark:text-red-400 border-red-200 dark:border-red-800' : 'bg-emerald-50 dark:bg-emerald-900/30 text-emerald-700 dark:text-emerald-400 border-emerald-200 dark:border-emerald-800'}`}>
                        {message.text}
                    </div>
                )}

                <div className="space-y-12 pb-20">
                    {/* Card 1: AI Provider Configuration */}
                    <div className="bg-white dark:bg-gray-800 rounded-3xl shadow-xl overflow-hidden border border-gray-100 dark:border-gray-700 backdrop-blur-sm">
                        <div className="p-6 border-b border-gray-100 dark:border-gray-700 bg-gray-50/30 dark:bg-gray-800/50">
                            <h2 className="text-xl font-black text-gray-900 dark:text-white flex items-center gap-3">
                                <svg className="w-6 h-6 text-indigo-500" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2.5} d="M19.428 15.428a2 2 0 00-1.022-.547l-2.387-.477a2 2 0 00-1.96 1.414l-.503 1.508a10 10 0 01-4.322-4.322l1.508-.503a2 2 0 001.414-1.96l-.477-2.387a2 2 0 00-.547-1.022L7.707 4.707a1 1 0 00-1.414 0l-1.586 1.586a1 1 0 00-.233 1.03 10.001 10.001 0 0011.95 11.95 1 1 0 001.03-.233l1.586-1.586a1 1 0 000-1.414l-1.586-1.586z" /></svg>
                                AI Resource Configuration
                            </h2>
                            <p className="text-xs text-gray-400 mt-1 uppercase font-bold tracking-widest">Manage your providers, models, and API keys</p>
                        </div>

                        {/* Config Tabs */}
                        <div className="flex border-b border-gray-200 dark:border-gray-700 bg-gray-50/50 dark:bg-gray-800/50 overflow-x-auto no-scrollbar">
                            {['llm', 'tts', 'stt'].map((tab) => (
                                <button
                                    key={tab}
                                    type="button"
                                    onClick={() => setActiveConfigTab(tab)}
                                    className={`flex-1 min-w-[100px] py-4 text-[10px] font-black uppercase tracking-widest transition-all duration-200 focus:outline-none ${activeConfigTab === tab
                                        ? 'text-indigo-600 dark:text-indigo-400 border-b-2 border-indigo-600 dark:border-indigo-400 bg-white dark:bg-gray-800'
                                        : 'text-gray-400 dark:text-gray-500 hover:text-gray-600 dark:hover:text-gray-300 hover:bg-gray-100/50 dark:hover:bg-gray-700/30'
                                        }`}
                                >
                                    {tab === 'llm' ? 'Models' : tab === 'tts' ? 'TTS' : 'STT'}
                                </button>
                            ))}
                        </div>

                        <form onSubmit={handleSave} className="p-6 sm:p-8 space-y-6">
                            {/* LLM Settings */}
                            {activeConfigTab === 'llm' && (
                                <div className={sectionClass}>
                                    {renderProviderSection('llm', providerLists.llm, false)}
                                </div>
                            )}

                            {/* TTS Settings */}
                            {activeConfigTab === 'tts' && (
                                <div className={sectionClass}>
                                    {renderProviderSection('tts', providerLists.tts, true)}
                                </div>
                            )}

                            {/* STT Settings */}
                            {activeConfigTab === 'stt' && (
                                <div className={sectionClass}>
                                    {renderProviderSection('stt', providerLists.stt, false)}
                                </div>
                            )}

                            <div className="pt-6 mt-6 border-t border-gray-100 dark:border-gray-700 flex items-center justify-end">
                                <button
                                    type="submit"
                                    disabled={saving}
                                    className="px-6 py-3 bg-indigo-600 hover:bg-indigo-700 text-white font-bold rounded-xl shadow-lg shadow-indigo-200 dark:shadow-indigo-900/50 transform transition duration-200 hover:scale-[1.02] focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 disabled:opacity-75 disabled:cursor-not-allowed disabled:transform-none flex items-center gap-2"
                                >
                                    {saving && (
                                        <svg className="animate-spin -ml-1 mr-2 h-5 w-5 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
                                            <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
                                            <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
                                        </svg>
                                    )}
                                    <span>Save Configuration</span>
                                </button>
                            </div>
                        </form>
                    </div>

                    {/* Card 2: Team & Access Management */}
                    <div className="bg-white dark:bg-gray-800 rounded-3xl shadow-xl overflow-hidden border border-gray-100 dark:border-gray-700 backdrop-blur-sm">
                        <div className="p-6 border-b border-gray-100 dark:border-gray-700 bg-gray-50/30 dark:bg-gray-800/50">
                            <h2 className="text-xl font-black text-gray-900 dark:text-white flex items-center gap-3">
                                <svg className="w-6 h-6 text-indigo-500" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2.5} d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z" /></svg>
                                Identity & Access Governance
                            </h2>
                            <p className="text-xs text-gray-400 mt-1 uppercase font-bold tracking-widest">Define groups, policies, and manage members</p>
                        </div>

                        {/* Admin Tabs */}
                        <div className="flex border-b border-gray-200 dark:border-gray-700 bg-gray-50/50 dark:bg-gray-800/50 overflow-x-auto no-scrollbar">
                            {['groups', 'users'].map((tab) => (
                                <button
                                    key={tab}
                                    type="button"
                                    onClick={() => setActiveAdminTab(tab)}
                                    className={`flex-1 min-w-[100px] py-4 text-[10px] font-black uppercase tracking-widest transition-all duration-200 focus:outline-none ${activeAdminTab === tab
                                        ? 'text-indigo-600 dark:text-indigo-400 border-b-2 border-indigo-600 dark:border-indigo-400 bg-white dark:bg-gray-800'
                                        : 'text-gray-400 dark:text-gray-500 hover:text-gray-600 dark:hover:text-gray-300 hover:bg-gray-100/50 dark:hover:bg-gray-700/30'
                                        }`}
                                >
                                    {tab === 'groups' ? 'Groups' : 'Users'}
                                </button>
                            ))}
                        </div>

                        <div className="p-6 sm:p-8">
                            {/* Groups Management */}
                            {activeAdminTab === 'groups' && (
                                <div className={sectionClass}>
                                    {!editingGroup ? (
                                        <div className="space-y-6">
                                            <div className="flex items-center justify-between">
                                                <h3 className="text-lg font-black flex items-center gap-3 text-gray-900 dark:text-white">
                                                    Registered Groups
                                                </h3>
                                                <button
                                                    type="button"
                                                    onClick={() => setEditingGroup({ id: 'new', name: '', description: '', policy: { llm: [], tts: [], stt: [] } })}
                                                    className="px-4 py-2 bg-indigo-600 hover:bg-indigo-700 text-white text-[10px] font-black uppercase tracking-widest rounded-lg shadow-md transition-all flex items-center gap-2"
                                                >
                                                    <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={3} d="M12 4v16m8-8H4" /></svg>
                                                    Add Group
                                                </button>
                                            </div>

                                            <div className="grid grid-cols-1 gap-4">
                                                {sortedGroups.map((g) => (
                                                    <div key={g.id} className={`p-4 border ${g.id === 'ungrouped' ? 'border-indigo-300 dark:border-indigo-700 bg-indigo-50/30 dark:bg-indigo-900/10' : 'border-gray-100 dark:border-gray-700 bg-gray-50/50 dark:bg-gray-900/30'} rounded-2xl flex justify-between items-center group/card hover:bg-white dark:hover:bg-gray-800 transition-all hover:shadow-md`}>
                                                        <div>
                                                            <h4 className="font-bold text-gray-900 dark:text-gray-100 flex items-center gap-2">
                                                                {g.id === 'ungrouped' ? 'Standard / Guest Policy' : g.name}
                                                                {g.id === 'ungrouped' && <span className="text-[10px] font-black uppercase tracking-widest text-indigo-600 dark:text-indigo-400 py-0.5 px-2 bg-indigo-100/50 dark:bg-indigo-900/40 rounded-full">Global Fallback</span>}
                                                            </h4>
                                                            <p className="text-xs text-gray-500 dark:text-gray-400 mt-1">
                                                                {g.id === 'ungrouped' ? 'Baseline access for all unassigned members.' : (g.description || 'No description')}
                                                            </p>
                                                            <div className="flex gap-2 mt-3">
                                                                {['llm', 'tts', 'stt'].map(section => (
                                                                    <div key={section} className="flex flex-col items-center">
                                                                        <span className="text-[9px] font-black uppercase tracking-tight text-gray-400 mb-1">{section}</span>
                                                                        <div className="flex -space-x-2">
                                                                            {g.policy?.[section]?.length > 0 ? (
                                                                                g.policy?.[section].slice(0, 3).map(p => (
                                                                                    <div key={p} className="w-5 h-5 rounded-full bg-indigo-100 dark:bg-indigo-900 border-2 border-white dark:border-gray-800 flex items-center justify-center text-[8px] font-bold text-indigo-600 dark:text-indigo-400" title={p}>
                                                                                        {p[0].toUpperCase()}
                                                                                    </div>
                                                                                ))
                                                                            ) : (
                                                                                <span className="text-[10px] text-gray-400 italic">None</span>
                                                                            )}
                                                                            {g.policy?.[section]?.length > 3 && (
                                                                                <div className="w-5 h-5 rounded-full bg-gray-100 dark:bg-gray-700 border-2 border-white dark:border-gray-800 flex items-center justify-center text-[8px] font-bold text-gray-500">
                                                                                    +{g.policy?.[section].length - 3}
                                                                                </div>
                                                                            )}
                                                                        </div>
                                                                    </div>
                                                                ))}
                                                            </div>
                                                        </div>
                                                        <div className="flex gap-2">
                                                            <button
                                                                type="button"
                                                                onClick={() => setEditingGroup(g)}
                                                                className="p-2 text-indigo-600 hover:bg-indigo-50 dark:hover:bg-indigo-900/30 rounded-lg transition-colors"
                                                            >
                                                                <svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z" /></svg>
                                                            </button>
                                                            {g.id !== 'ungrouped' && (
                                                                <button
                                                                    type="button"
                                                                    onClick={() => handleDeleteGroup(g.id)}
                                                                    className="p-2 text-red-500 hover:bg-red-50 dark:hover:bg-red-900/30 rounded-lg transition-colors"
                                                                >
                                                                    <svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" /></svg>
                                                                </button>
                                                            )}
                                                        </div>
                                                    </div>
                                                ))}
                                            </div>
                                        </div>
                                    ) : (
                                        <div className="animate-fade-in space-y-6">
                                            {/* (Group editing form - unchanged logic, just cleaner container) */}
                                            <div className="flex items-center gap-4">
                                                <button type="button" onClick={() => setEditingGroup(null)} className="p-2 text-gray-400 hover:text-gray-600 dark:hover:text-gray-200">
                                                    <svg className="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 19l-7-7m0 0l7-7m-7 7h18" /></svg>
                                                </button>
                                                <h3 className="text-xl font-black text-gray-900 dark:text-white">
                                                    {editingGroup.id === 'new' ? 'New Group Policy' : `Edit: ${editingGroup.id === 'ungrouped' ? 'Standard / Guest Policy' : editingGroup.name}`}
                                                </h3>
                                                {editingGroup.id === 'ungrouped' && (
                                                    <span className="text-[10px] font-black uppercase tracking-widest text-amber-700 dark:text-amber-400 py-1 px-2.5 bg-amber-100/60 dark:bg-amber-900/30 border border-amber-200 dark:border-amber-800 rounded-full flex items-center gap-1">
                                                        <svg className="w-3 h-3" fill="currentColor" viewBox="0 0 20 20"><path fillRule="evenodd" d="M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z" clipRule="evenodd" /></svg>
                                                        System Group
                                                    </span>
                                                )}
                                            </div>

                                            <div className="bg-gray-50/50 dark:bg-gray-900/30 p-6 rounded-3xl border border-gray-100 dark:border-gray-700 space-y-6">
                                                <div className="grid grid-cols-1 sm:grid-cols-2 gap-6">
                                                    <div>
                                                        <label className={labelClass}>Group Name</label>
                                                        <input
                                                            value={editingGroup.id === 'ungrouped' ? 'Ungrouped (System Default)' : editingGroup.name}
                                                            onChange={e => editingGroup.id !== 'ungrouped' && setEditingGroup({ ...editingGroup, name: e.target.value })}
                                                            readOnly={editingGroup.id === 'ungrouped'}
                                                            placeholder="Engineering, Designers, etc."
                                                            className={`${inputClass} ${editingGroup.id === 'ungrouped'
                                                                ? 'opacity-60 cursor-not-allowed bg-gray-100 dark:bg-gray-700 text-gray-500 dark:text-gray-400'
                                                                : (editingGroup.name.trim() &&
                                                                    allGroups.some(g => g.id !== editingGroup.id && g.name.toLowerCase() === editingGroup.name.trim().toLowerCase())
                                                                    ? '!border-red-400 dark:!border-red-600 !ring-red-300'
                                                                    : '')
                                                                }`}
                                                        />
                                                        {editingGroup.id === 'ungrouped' ? (
                                                            <p className="mt-1.5 text-xs text-amber-600 dark:text-amber-400 font-medium flex items-center gap-1">
                                                                <svg className="w-3.5 h-3.5" fill="currentColor" viewBox="0 0 20 20"><path fillRule="evenodd" d="M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z" clipRule="evenodd" /></svg>
                                                                System group name is locked. Only the access policy can be changed.
                                                            </p>
                                                        ) : editingGroup.name.trim() &&
                                                        allGroups.some(g => g.id !== editingGroup.id && g.name.toLowerCase() === editingGroup.name.trim().toLowerCase()) && (
                                                            <p className="mt-1.5 text-xs font-semibold text-red-500 flex items-center gap-1">
                                                                <svg className="w-3.5 h-3.5" fill="currentColor" viewBox="0 0 20 20"><path fillRule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clipRule="evenodd" /></svg>
                                                                A group with this name already exists
                                                            </p>
                                                        )}
                                                    </div>
                                                    <div>
                                                        <label className={labelClass}>Description</label>
                                                        <input
                                                            value={editingGroup.description || ''}
                                                            onChange={e => setEditingGroup({ ...editingGroup, description: e.target.value })}
                                                            placeholder="Short description of this group..."
                                                            className={inputClass}
                                                        />
                                                    </div>
                                                </div>

                                                <div className="border-t border-gray-200 dark:border-gray-700 pt-6">
                                                    <label className="text-sm font-black uppercase tracking-widest text-gray-500 mb-4 block">Provider Access Policy (Whitelists)</label>

                                                    <div className="grid grid-cols-1 gap-8">
                                                        {['llm', 'tts', 'stt'].map(section => (
                                                            <div key={section} className="space-y-3">
                                                                <div className="flex items-center justify-between mb-2">
                                                                    <span className="text-[10px] font-black uppercase tracking-widest text-gray-400">{section} Access</span>
                                                                    <div className="flex gap-2">
                                                                        <button type="button" onClick={() => {
                                                                            const configuredIds = effective[section]?.providers ? Object.keys(effective[section].providers) : [];
                                                                            setEditingGroup({ ...editingGroup, policy: { ...editingGroup.policy, [section]: configuredIds } })
                                                                        }} className="text-[10px] font-bold text-indigo-600 dark:text-indigo-400 hover:underline">Select All Configured</button>
                                                                        <button type="button" onClick={() => setEditingGroup({ ...editingGroup, policy: { ...editingGroup.policy, [section]: [] } })} className="text-[10px] font-bold text-red-600 dark:text-red-400 hover:underline">Clear</button>
                                                                    </div>
                                                                </div>
                                                                <div className="grid grid-cols-2 sm:grid-cols-3 gap-2">
                                                                    {(effective[section]?.providers ? Object.keys(effective[section].providers) : []).map(pId => {
                                                                        const isChecked = (editingGroup.policy?.[section] || []).includes(pId);
                                                                        // Resolve label for display
                                                                        const baseType = pId.split('_')[0];
                                                                        const baseDef = providerLists[section].find(ld => ld.id === baseType || ld.id === pId);
                                                                        const label = baseDef ? (pId.includes('_') ? `${baseDef.label} (${pId.split('_').slice(1).join('_')})` : baseDef.label) : pId;

                                                                        return (
                                                                            <label key={pId} className={`flex items-center gap-2 px-3 py-2 rounded-xl border cursor-pointer transition-all ${isChecked ? 'bg-indigo-50 dark:bg-indigo-900/30 border-indigo-200 dark:border-indigo-800' : 'border-gray-100 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-800/50'}`}>
                                                                                <input
                                                                                    type="checkbox"
                                                                                    checked={isChecked}
                                                                                    onChange={(e) => {
                                                                                        const current = editingGroup.policy?.[section] || [];
                                                                                        const next = e.target.checked ? [...current, pId] : current.filter(x => x !== pId);
                                                                                        setEditingGroup({ ...editingGroup, policy: { ...editingGroup.policy, [section]: next } });
                                                                                    }}
                                                                                    className="rounded border-gray-300 dark:border-gray-600 text-indigo-600 focus:ring-indigo-500"
                                                                                />
                                                                                <span className="text-[11px] font-bold text-gray-700 dark:text-gray-300 truncate">{label}</span>
                                                                            </label>
                                                                        );
                                                                    })}
                                                                </div>
                                                            </div>
                                                        ))}
                                                    </div>
                                                </div>

                                                <div className="flex justify-end gap-3 pt-4">
                                                    <button type="button" onClick={() => setEditingGroup(null)} className="px-6 py-2 rounded-xl text-sm font-bold text-gray-500 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors">Cancel</button>
                                                    <button type="button" onClick={handleSaveGroup} disabled={saving || !editingGroup.name || allGroups.some(g => g.id !== editingGroup.id && g.name.toLowerCase() === editingGroup.name.trim().toLowerCase())} className="px-8 py-2 bg-indigo-600 text-white rounded-xl text-sm font-black uppercase tracking-widest shadow-lg shadow-indigo-200 dark:shadow-indigo-900/50 hover:bg-indigo-700 disabled:opacity-50 transition-all">
                                                        {saving ? 'Saving...' : 'Save Group'}
                                                    </button>
                                                </div>
                                            </div>
                                        </div>
                                    )}
                                </div>
                            )}

                            {/* Users Management */}
                            {activeAdminTab === 'users' && (
                                <div className={sectionClass}>
                                    <div className="space-y-6">
                                        <div className="flex flex-col sm:flex-row items-center justify-between gap-4">
                                            <h3 className="text-lg font-black flex items-center gap-3 text-gray-900 dark:text-white">
                                                Active Roster
                                                <span className="text-[10px] py-0.5 px-2 bg-gray-100 dark:bg-gray-700 text-gray-400 rounded-full">{filteredUsers.length}</span>
                                            </h3>
                                            <div className="flex items-center gap-3 w-full sm:w-auto">
                                                <div className="relative flex-1 sm:min-w-[250px]">
                                                    <input
                                                        type="text"
                                                        value={userSearch}
                                                        onChange={e => setUserSearch(e.target.value)}
                                                        placeholder="Search by name, email..."
                                                        className="w-full text-xs p-2.5 pl-9 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-xl focus:ring-2 focus:ring-indigo-500 outline-none transition-all"
                                                    />
                                                    <svg className="w-4 h-4 text-gray-400 absolute left-3 top-1/2 -translate-y-1/2" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2.5} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" /></svg>
                                                </div>
                                                <button onClick={loadUsers} className="p-2.5 text-indigo-600 hover:bg-indigo-50 dark:hover:bg-indigo-900/30 border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-xl transition-colors">
                                                    <svg className={`w-4 h-4 ${usersLoading ? 'animate-spin' : ''}`} fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" /></svg>
                                                </button>
                                            </div>
                                        </div>
                                        <div className="overflow-hidden border border-gray-100 dark:border-gray-700 rounded-2xl shadow-sm bg-gray-50/50 dark:bg-gray-900/30">
                                            <table className="w-full text-left border-collapse">
                                                <thead className="bg-white dark:bg-gray-800">
                                                    <tr>
                                                        <th className="px-6 py-4 text-[9px] font-black uppercase tracking-widest text-gray-500">Member</th>
                                                        <th className="px-6 py-4 text-[9px] font-black uppercase tracking-widest text-gray-500">Policy Group</th>
                                                        <th className="px-6 py-4 text-[9px] font-black uppercase tracking-widest text-gray-500">Activity Auditing</th>
                                                        <th className="px-6 py-4 text-[9px] font-black uppercase tracking-widest text-gray-500 text-right">Actions</th>
                                                    </tr>
                                                </thead>
                                                <tbody className="divide-y divide-gray-100 dark:divide-gray-800">
                                                    {filteredUsers.map((u) => (
                                                        <tr key={u.id} className="hover:bg-white dark:hover:bg-gray-800/50 transition-colors">
                                                            <td className="px-6 py-4">
                                                                <div className="flex items-center gap-3">
                                                                    <div className={`w-8 h-8 rounded-full flex items-center justify-center text-[10px] font-black ${u.role === 'admin' ? 'bg-indigo-100 text-indigo-700 dark:bg-indigo-900/40 dark:text-indigo-300' : 'bg-gray-100 text-gray-700 dark:bg-gray-700 dark:text-gray-300'}`}>
                                                                        {(u.username || u.email || '?')[0].toUpperCase()}
                                                                    </div>
                                                                    <div>
                                                                        <p className="text-xs font-black text-gray-900 dark:text-white truncate max-w-[150px]">{u.username || u.email}</p>
                                                                        <p className="text-[10px] text-gray-400 font-bold uppercase tracking-tight">{u.role}</p>
                                                                    </div>
                                                                </div>
                                                            </td>
                                                            <td className="px-6 py-4">
                                                                <select
                                                                    value={u.group_id || 'ungrouped'}
                                                                    onChange={(e) => handleGroupChange(u.id, e.target.value)}
                                                                    className="text-xs p-1.5 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg outline-none focus:ring-1 focus:ring-indigo-500 transition-all font-bold text-gray-600 dark:text-gray-300 min-w-[150px]"
                                                                >
                                                                    {sortedGroups.map(g => (
                                                                        <option key={g.id} value={g.id}>
                                                                            {g.id === 'ungrouped' ? 'Standard / Guest' : g.name}
                                                                        </option>
                                                                    ))}
                                                                </select>
                                                            </td>
                                                            <td className="px-6 py-4">
                                                                <div className="space-y-1">
                                                                    <div className="flex items-center gap-1.5">
                                                                        <span className="text-[9px] font-black uppercase text-gray-400">Join:</span>
                                                                        <span className="text-[10px] font-bold text-gray-600 dark:text-gray-300">{new Date(u.created_at).toLocaleDateString()}</span>
                                                                    </div>
                                                                    <div className="flex items-center gap-1.5">
                                                                        <span className="text-[9px] font-black uppercase text-gray-400">Last:</span>
                                                                        <span className="text-[10px] font-bold text-indigo-600 dark:text-indigo-400">
                                                                            {u.last_login_at ? new Date(u.last_login_at).toLocaleDateString() : 'Never'}
                                                                        </span>
                                                                    </div>
                                                                </div>
                                                            </td>
                                                            <td className="px-6 py-4 text-right">
                                                                <button
                                                                    type="button"
                                                                    onClick={(e) => { e.preventDefault(); handleRoleToggle(u); }}
                                                                    className={`text-[9px] font-black uppercase tracking-widest transition-all ${u.role === 'admin'
                                                                        ? 'text-red-600 hover:text-red-700'
                                                                        : 'text-indigo-600 hover:text-indigo-700'
                                                                        }`}
                                                                >
                                                                    {u.role === 'admin' ? 'Demote' : 'Promote'}
                                                                </button>
                                                            </td>
                                                        </tr>
                                                    ))}
                                                </tbody>
                                            </table>
                                            {allUsers.length === 0 && !usersLoading && (
                                                <div className="p-12 text-center text-gray-400 italic text-sm">No other users found.</div>
                                            )}
                                        </div>
                                    </div>
                                </div>
                            )}
                        </div>
                    </div>
                </div>
            </div>
            {showVoicesModal && (
                <div className="fixed inset-0 z-[100] flex items-center justify-center bg-black/50 p-4 transition-opacity" onClick={() => setShowVoicesModal(false)}>
                    <div className="bg-white dark:bg-gray-800 rounded-xl max-w-lg w-full p-6 shadow-2xl relative max-h-[85vh] flex flex-col" onClick={e => e.stopPropagation()}>
                        <div className="flex justify-between items-center mb-4 border-b border-gray-100 dark:border-gray-700 pb-3">
                            <div>
                                <h3 className="text-xl font-bold text-gray-900 dark:text-gray-100">Available Cloud Voices</h3>
                                <p className="text-xs text-gray-500 mt-1">Found {voiceList.length} voices to choose from.</p>
                                <p className="text-xs text-indigo-500 font-medium mt-1">Highlighted voices (Chirp, Journey, Studio) use advanced AI for highest quality.</p>
                            </div>
                            <button onClick={() => setShowVoicesModal(false)} className="text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 text-3xl font-bold focus:outline-none">&times;</button>
                        </div>
                        <div className="overflow-y-auto flex-1 bg-gray-50 dark:bg-gray-900/50 border border-gray-100 dark:border-gray-700 p-2 rounded-lg">
                            {voicesLoading ? (
                                <div className="flex h-32 items-center justify-center">
                                    <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-indigo-600 dark:border-indigo-400"></div>
                                </div>
                            ) : voiceList.length > 0 ? (
                                <ul className="space-y-[2px]">
                                    {voiceList.map((v, i) => {
                                        let highlight = v.toLowerCase().includes('chirp') || v.toLowerCase().includes('journey') || v.toLowerCase().includes('studio');
                                        return (
                                            <li key={i} className={`text-sm cursor-text font-mono select-all p-2 hover:bg-white dark:hover:bg-gray-800 rounded transition-colors border border-transparent hover:border-gray-200 dark:hover:border-gray-600 ${highlight ? 'text-indigo-600 dark:text-indigo-400 font-semibold' : 'text-gray-600 dark:text-gray-400'}`}>
                                                {v}
                                            </li>
                                        )
                                    })}
                                </ul>
                            ) : (
                                <p className="text-center text-gray-500 mt-8">No voices found. Make sure your API key is configured and valid.</p>
                            )}
                        </div>
                        <div className="mt-4 text-xs text-gray-500 dark:text-gray-400 flex justify-between items-center">
                            <span>Double-click a name to select it, then paste it into the field.</span>
                            <button onClick={() => setShowVoicesModal(false)} className="px-4 py-2 bg-gray-100 hover:bg-gray-200 dark:bg-gray-700 dark:hover:bg-gray-600 text-gray-700 dark:text-gray-300 rounded-lg transition-colors font-medium">Close</button>
                        </div>
                    </div>
                </div>
            )}
        </div>
    );
};

export default SettingsPage;