// Shoes Proxy Configuration Studio - Web Application
class ShoesConfigStudio {
    constructor() {
        this.configs = {
            servers: [],
            clientGroups: [],
            ruleGroups: [],
            namedPems: []
        };
        
        this.currentEditingId = null;
        this.currentEditingType = null;
        
        // API base URL
        this.apiBase = '/api/v1';
        
        this.init();
    }

    async init() {
        this.setupEventListeners();
        this.setupNavigation();
        await this.loadConfiguration();
    }

    // API Client Methods
    async apiCall(method, endpoint, data = null) {
        const options = {
            method: method,
            headers: {
                'Content-Type': 'application/json'
            }
        };

        if (data && method !== 'GET') {
            options.body = JSON.stringify(data);
        }

        try {
            this.showLoading(true);
            const response = await fetch(`${this.apiBase}${endpoint}`, options);
            
            if (endpoint === '/export' && response.ok) {
                // Export endpoint returns text/plain
                return await response.text();
            }
            
            const result = await response.json();

            if (!response.ok) {
                throw new Error(result.error || `HTTP ${response.status}: ${response.statusText}`);
            }

            return result;
        } catch (error) {
            if (error.name === 'TypeError' && error.message.includes('Failed to fetch')) {
                throw new Error('Unable to connect to server. Please ensure the server is running.');
            }
            throw error;
        } finally {
            this.showLoading(false);
        }
    }

    async loadConfiguration() {
        try {
            const result = await this.apiCall('GET', '/config');
            
            if (result.success && result.data) {
                // Transform the data to match our internal format
                this.configs.servers = result.data.servers || [];
                this.configs.clientGroups = result.data.client_groups ? 
                    result.data.client_groups.map(g => ({
                        id: g.name,  // Use name as ID
                        name: g.name,
                        proxies: g.proxies
                    })) : [];
                this.configs.ruleGroups = result.data.rule_groups ? 
                    result.data.rule_groups.map(g => ({
                        id: g.name,  // Use name as ID
                        name: g.name,
                        rules: g.rules
                    })) : [];
                this.configs.namedPems = result.data.named_pems || [];
                
                // Add built-in groups if not present
                this.ensureBuiltinGroups();
                
                this.updateCounts();
                this.updateRuleSelects();
                this.renderSection(this.getCurrentSection());
            }
        } catch (error) {
            this.showToast('error', `Failed to load configuration: ${error.message}`);
            // Add built-in groups as fallback
            this.ensureBuiltinGroups();
            this.updateCounts();
            this.updateRuleSelects();
        }
    }

    ensureBuiltinGroups() {
        // Ensure direct client group exists
        if (!this.configs.clientGroups.find(g => g.name === 'direct')) {
            this.configs.clientGroups.push({
                id: 'direct',
                name: 'direct',
                proxies: [{
                    protocol: { type: 'direct' },
                    address: 'unspecified',
                    transport: 'tcp'
                }]
            });
        }

        // Ensure allow-all-direct rule group exists
        if (!this.configs.ruleGroups.find(g => g.name === 'allow-all-direct')) {
            this.configs.ruleGroups.push({
                id: 'allow-all-direct',
                name: 'allow-all-direct',
                rules: [{
                    masks: ['0.0.0.0/0'],
                    action: {
                        type: 'allow',
                        client_proxies: ['direct']
                    }
                }]
            });
        }

        // Ensure block-all rule group exists
        if (!this.configs.ruleGroups.find(g => g.name === 'block-all')) {
            this.configs.ruleGroups.push({
                id: 'block-all',
                name: 'block-all',
                rules: [{
                    masks: ['0.0.0.0/0'],
                    action: { type: 'block' }
                }]
            });
        }
    }

    showLoading(show) {
        const overlay = document.getElementById('loading-overlay');
        if (show) {
            overlay.classList.add('active');
        } else {
            overlay.classList.remove('active');
        }
    }

    getCurrentSection() {
        const activeNav = document.querySelector('.nav-link.active');
        return activeNav ? activeNav.dataset.section : 'servers';
    }

    setupEventListeners() {
        // Navigation
        document.querySelectorAll('.nav-link').forEach(link => {
            link.addEventListener('click', (e) => {
                e.preventDefault();
                const section = link.dataset.section;
                this.switchSection(section);
            });
        });

        // Add buttons
        document.getElementById('add-config').addEventListener('click', () => {
            const section = this.getCurrentSection();
            switch (section) {
                case 'servers':
                    this.openServerModal();
                    break;
                case 'client-groups':
                    this.openClientGroupModal();
                    break;
                case 'rule-groups':
                    this.openRuleGroupModal();
                    break;
                case 'named-pems':
                    this.openNamedPemModal();
                    break;
            }
        });

        // Modal events
        this.setupModalEvents();
        
        // Import/Export events
        this.setupImportExportEvents();
        
        // Validation events
        document.getElementById('validate-config').addEventListener('click', () => {
            this.validateConfiguration();
        });

        // Preview YAML
        document.getElementById('preview-yaml').addEventListener('click', () => {
            this.showYamlPreview();
        });

        // Server form events
        this.setupServerFormEvents();

        // Client Group events
        this.setupClientGroupEvents();

        // Rule Group events
        this.setupRuleGroupEvents();

        // Named PEM events
        this.setupNamedPemEvents();
    }

    setupModalEvents() {
        // Close modals
        document.querySelectorAll('.modal-close, .modal').forEach(element => {
            element.addEventListener('click', (e) => {
                if (e.target === element || e.target.classList.contains('modal-close')) {
                    this.closeModals();
                }
            });
        });

        // Cancel buttons
        document.getElementById('cancel-server').addEventListener('click', () => {
            this.closeModals();
        });

        // Form submissions
        document.getElementById('server-form').addEventListener('submit', (e) => {
            e.preventDefault();
            this.saveServerConfig();
        });
    }

    setupServerFormEvents() {
        const transportSelect = document.getElementById('server-transport');
        const protocolSelect = document.getElementById('server-protocol-type');
        const bindTypeSelect = document.getElementById('server-bind-type');

        transportSelect.addEventListener('change', () => {
            this.updateTransportSettings();
        });

        protocolSelect.addEventListener('change', () => {
            this.updateProtocolFields();
        });

        bindTypeSelect.addEventListener('change', () => {
            this.updateBindLocationPlaceholder();
        });
    }

    setupClientGroupEvents() {
        // Add client proxy button
        document.getElementById('add-client-proxy').addEventListener('click', () => {
            this.addClientProxyToForm();
        });

        // Form submission
        document.getElementById('client-group-form').addEventListener('submit', (e) => {
            e.preventDefault();
            this.saveClientGroup();
        });

        // Cancel button
        document.getElementById('cancel-client-group').addEventListener('click', () => {
            this.closeModals();
        });
    }

    setupRuleGroupEvents() {
        // Add rule button
        document.getElementById('add-rule').addEventListener('click', () => {
            this.addRuleToForm();
        });

        // Form submission
        document.getElementById('rule-group-form').addEventListener('submit', (e) => {
            e.preventDefault();
            this.saveRuleGroup();
        });

        // Cancel button
        document.getElementById('cancel-rule-group').addEventListener('click', () => {
            this.closeModals();
        });
    }

    setupNamedPemEvents() {
        // Form submission
        document.getElementById('named-pem-form').addEventListener('submit', (e) => {
            e.preventDefault();
            this.saveNamedPem();
        });

        // Cancel button
        document.getElementById('cancel-named-pem').addEventListener('click', () => {
            this.closeModals();
        });
    }

    setupImportExportEvents() {
        const fileInput = document.getElementById('file-input');
        const fileUploadArea = document.getElementById('file-upload-area');
        
        fileInput.addEventListener('change', (e) => {
            if (e.target.files[0]) {
                this.importConfiguration(e.target.files[0]);
            }
        });

        fileUploadArea.addEventListener('click', () => {
            fileInput.click();
        });

        // Drag and drop
        fileUploadArea.addEventListener('dragover', (e) => {
            e.preventDefault();
            fileUploadArea.classList.add('drag-over');
        });

        fileUploadArea.addEventListener('dragleave', () => {
            fileUploadArea.classList.remove('drag-over');
        });

        fileUploadArea.addEventListener('drop', (e) => {
            e.preventDefault();
            fileUploadArea.classList.remove('drag-over');
            const file = e.dataTransfer.files[0];
            if (file) {
                this.importConfiguration(file);
            }
        });

        // Export buttons
        document.getElementById('export-yaml').addEventListener('click', () => {
            this.exportConfiguration();
        });

        document.getElementById('copy-yaml').addEventListener('click', () => {
            this.copyConfigurationToClipboard();
        });
    }

    setupNavigation() {
        // Set initial section
        this.switchSection('servers');
    }

    switchSection(sectionName) {
        // Update navigation
        document.querySelectorAll('.nav-link').forEach(link => {
            link.classList.remove('active');
        });
        document.querySelector(`[data-section="${sectionName}"]`).classList.add('active');

        // Update content
        document.querySelectorAll('.content-section').forEach(section => {
            section.classList.remove('active');
        });
        document.getElementById(`${sectionName}-section`).classList.add('active');

        // Update header
        const titles = {
            'servers': 'Server Configurations',
            'client-groups': 'Client Proxy Groups', 
            'rule-groups': 'Rule Groups',
            'named-pems': 'Named PEM Files',
            'import-export': 'Import & Export',
            'validation': 'Configuration Validation'
        };
        document.getElementById('section-title').textContent = titles[sectionName];

        // Update add button
        const addBtn = document.getElementById('add-config');
        const addBtnTexts = {
            'servers': 'Add Server',
            'client-groups': 'Add Client Group',
            'rule-groups': 'Add Rule Group',
            'named-pems': 'Add Named PEM'
        };

        if (addBtnTexts[sectionName]) {
            addBtn.style.display = 'flex';
            addBtn.innerHTML = `<i class="fas fa-plus"></i> ${addBtnTexts[sectionName]}`;
        } else {
            addBtn.style.display = 'none';
        }

        // Render section content
        this.renderSection(sectionName);
    }

    renderSection(sectionName) {
        switch (sectionName) {
            case 'servers':
                this.renderServers();
                break;
            case 'client-groups':
                this.renderClientGroups();
                break;
            case 'rule-groups':
                this.renderRuleGroups();
                break;
            case 'named-pems':
                this.renderNamedPems();
                break;
        }
    }

    renderServers() {
        const container = document.getElementById('servers-list');
        
        if (this.configs.servers.length === 0) {
            container.innerHTML = `
                <div class="empty-state">
                    <i class="fas fa-server"></i>
                    <h4>No servers configured</h4>
                    <p>Click "Add Server" to create your first proxy server configuration</p>
                </div>
            `;
            return;
        }

        container.innerHTML = this.configs.servers.map(server => {
            // Get bind location string for use as ID
            const bindLocationStr = this.getServerBindLocationString(server);
            const bindLocationEncoded = encodeURIComponent(bindLocationStr);
            
            return `
            <div class="config-item">
                <div class="config-item-header">
                    <div class="config-item-title">
                        <i class="fas fa-server"></i>
                        ${bindLocationStr}
                    </div>
                    <div class="config-item-actions">
                        <button class="btn-icon" onclick="app.editServer('${bindLocationEncoded}')" title="Edit">
                            <i class="fas fa-edit"></i>
                        </button>
                        <button class="btn-icon" onclick="app.duplicateServer('${bindLocationEncoded}')" title="Duplicate">
                            <i class="fas fa-copy"></i>
                        </button>
                        <button class="btn-icon" onclick="app.deleteServer('${bindLocationEncoded}')" title="Delete">
                            <i class="fas fa-trash"></i>
                        </button>
                    </div>
                </div>
                <div class="config-item-details">
                    <div class="config-detail">
                        <i class="fas fa-network-wired"></i>
                        <span class="protocol-badge protocol-${server.protocol.type}">${server.protocol.type.toUpperCase()}</span>
                        <span class="transport-badge">${server.transport.toUpperCase()}</span>
                    </div>
                    ${server.protocol.username ? `
                        <div class="config-detail">
                            <i class="fas fa-user"></i>
                            Authentication: ${server.protocol.username}
                        </div>
                    ` : ''}
                    ${server.rules && server.rules.length > 0 ? `
                        <div class="config-detail">
                            <i class="fas fa-shield-alt"></i>
                            Rules: ${server.rules[0]}
                        </div>
                    ` : ''}
                </div>
            </div>
            `;
        }).join('');
    }
    
    getServerBindLocationString(server) {
        if (server.bind_location) {
            return server.bind_location.value;
        }
        // Fallback for old format
        return server.bindLocation || '';
    }

    renderClientGroups() {
        const container = document.getElementById('client-groups-list');
        
        const customGroups = this.configs.clientGroups.filter(g => 
            !['direct'].includes(g.id)
        );

        if (customGroups.length === 0) {
            container.innerHTML = `
                <div class="empty-state">
                    <i class="fas fa-users"></i>
                    <h4>No client groups configured</h4>
                    <p>Click "Add Client Group" to create reusable proxy configurations</p>
                </div>
            `;
            return;
        }

        container.innerHTML = customGroups.map(group => `
            <div class="config-item">
                <div class="config-item-header">
                    <div class="config-item-title">
                        <i class="fas fa-users"></i>
                        ${group.name}
                    </div>
                    <div class="config-item-actions">
                        <button class="btn-icon" onclick="app.editClientGroup('${group.id}')" title="Edit">
                            <i class="fas fa-edit"></i>
                        </button>
                        <button class="btn-icon" onclick="app.deleteClientGroup('${group.id}')" title="Delete">
                            <i class="fas fa-trash"></i>
                        </button>
                    </div>
                </div>
                <div class="config-item-details">
                    <div class="config-detail">
                        <i class="fas fa-list"></i>
                        ${group.proxies.length} proxy configuration${group.proxies.length !== 1 ? 's' : ''}
                    </div>
                    <div class="config-detail">
                        <i class="fas fa-network-wired"></i>
                        Protocols: ${[...new Set(group.proxies.map(p => p.protocol.type))].join(', ')}
                    </div>
                </div>
            </div>
        `).join('');
    }

    renderRuleGroups() {
        const container = document.getElementById('rule-groups-list');
        
        const customGroups = this.configs.ruleGroups.filter(g => 
            !['allow-all-direct', 'block-all'].includes(g.id)
        );

        if (customGroups.length === 0) {
            container.innerHTML = `
                <div class="empty-state">
                    <i class="fas fa-shield-alt"></i>
                    <h4>No rule groups configured</h4>
                    <p>Click "Add Rule Group" to create routing and access control rules</p>
                </div>
            `;
            return;
        }

        container.innerHTML = customGroups.map(group => `
            <div class="config-item">
                <div class="config-item-header">
                    <div class="config-item-title">
                        <i class="fas fa-shield-alt"></i>
                        ${group.name}
                    </div>
                    <div class="config-item-actions">
                        <button class="btn-icon" onclick="app.editRuleGroup('${group.id}')" title="Edit">
                            <i class="fas fa-edit"></i>
                        </button>
                        <button class="btn-icon" onclick="app.deleteRuleGroup('${group.id}')" title="Delete">
                            <i class="fas fa-trash"></i>
                        </button>
                    </div>
                </div>
                <div class="config-item-details">
                    <div class="config-detail">
                        <i class="fas fa-list"></i>
                        ${group.rules.length} rule${group.rules.length !== 1 ? 's' : ''}
                    </div>
                    <div class="config-detail">
                        <i class="fas fa-gavel"></i>
                        Actions: ${[...new Set(group.rules.map(r => r.action.type || r.action))].join(', ')}
                    </div>
                </div>
            </div>
        `).join('');
    }

    renderNamedPems() {
        const container = document.getElementById('named-pems-list');
        
        if (this.configs.namedPems.length === 0) {
            container.innerHTML = `
                <div class="empty-state">
                    <i class="fas fa-certificate"></i>
                    <h4>No named PEMs configured</h4>
                    <p>Click "Add Named PEM" to create reusable certificates and keys</p>
                </div>
            `;
            return;
        }

        container.innerHTML = this.configs.namedPems.map(pem => `
            <div class="config-item">
                <div class="config-item-header">
                    <div class="config-item-title">
                        <i class="fas fa-certificate"></i>
                        ${pem.pem}
                    </div>
                    <div class="config-item-actions">
                        <button class="btn-icon" onclick="app.editNamedPem('${pem.pem}')" title="Edit">
                            <i class="fas fa-edit"></i>
                        </button>
                        <button class="btn-icon" onclick="app.deleteNamedPem('${pem.pem}')" title="Delete">
                            <i class="fas fa-trash"></i>
                        </button>
                    </div>
                </div>
                <div class="config-item-details">
                    <div class="config-detail">
                        <i class="fas fa-key"></i>
                        ${pem.data ? 'Embedded PEM data' : 'File path reference'}
                    </div>
                    ${pem.data ? `
                        <div class="config-detail">
                            <i class="fas fa-file-alt"></i>
                            Size: ${(pem.data.length / 1024).toFixed(1)} KB
                        </div>
                    ` : ''}
                </div>
            </div>
        `).join('');
    }

    // PEM Field Helper
    createPemFieldHTML(id, name, required = false) {
        const reqAttr = required ? 'required' : '';
        const existingPems = this.configs.namedPems || [];
        
        return `
            <div class="pem-field-wrapper">
                <select class="pem-select" id="${id}" name="${name}" ${reqAttr} 
                        onchange="app.handlePemSelectChange('${id}')">
                    <option value="">-- Select Option --</option>
                    <optgroup label="Existing Named PEMs">
                        ${existingPems.map(pem => 
                            `<option value="${pem.pem}">${pem.pem}</option>`
                        ).join('')}
                    </optgroup>
                    <option value="__new__">➕ Create New Named PEM</option>
                    <option value="__inline__">📋 Paste PEM Data Inline</option>
                </select>
                <div id="${id}-extra" class="pem-extra-input" style="display: none;">
                    <!-- Extra input will be inserted here based on selection -->
                </div>
            </div>
        `;
    }

    handlePemSelectChange(fieldId) {
        const select = document.getElementById(fieldId);
        const extraDiv = document.getElementById(`${fieldId}-extra`);
        const value = select.value;
        
        if (value === '__new__') {
            extraDiv.innerHTML = `
                <div class="pem-new-fields">
                    <input type="text" id="${fieldId}-new-name" 
                           placeholder="New PEM name (e.g., my-server-cert)" 
                           class="form-control" />
                    <textarea id="${fieldId}-new-data" 
                              placeholder="Paste PEM data here (-----BEGIN CERTIFICATE-----)" 
                              class="form-control" rows="4"></textarea>
                    <small class="help-text">This will create a new named PEM that can be reused</small>
                </div>
            `;
            extraDiv.style.display = 'block';
        } else if (value === '__inline__') {
            extraDiv.innerHTML = `
                <div class="pem-inline-field">
                    <textarea id="${fieldId}-inline" 
                              placeholder="Paste PEM data directly (-----BEGIN CERTIFICATE-----)\n⚠️ This is inline data, NOT a file path!" 
                              class="form-control pem-inline-textarea" rows="4"></textarea>
                    <small class="help-text warning">⚠️ This PEM data will be embedded directly in the config</small>
                </div>
            `;
            extraDiv.style.display = 'block';
        } else {
            extraDiv.style.display = 'none';
            extraDiv.innerHTML = '';
        }
    }

    // Get the actual PEM value based on the field selection
    getPemFieldValue(fieldId) {
        const select = document.getElementById(fieldId);
        const value = select.value;
        
        if (value === '__new__') {
            // Create the named PEM first, then return the name
            const name = document.getElementById(`${fieldId}-new-name`)?.value;
            const data = document.getElementById(`${fieldId}-new-data`)?.value;
            if (name && data) {
                // We'll handle the creation in the save function
                return { type: 'new', name, data };
            }
            return null;
        } else if (value === '__inline__') {
            const data = document.getElementById(`${fieldId}-inline`)?.value;
            return data ? { type: 'inline', data } : null;
        } else if (value) {
            return { type: 'reference', name: value };
        }
        return null;
    }
    
    // Process PEM field and create named PEM if needed
    async processPemField(fieldId) {
        const pemValue = this.getPemFieldValue(fieldId);
        if (!pemValue) return null;
        
        if (pemValue.type === 'new') {
            // Create new named PEM
            try {
                await this.apiCall('POST', '/named-pems', {
                    pem: pemValue.name,
                    data: pemValue.data
                });
                // Reload configs to get the new named PEM
                await this.loadConfiguration();
                return pemValue.name;
            } catch (error) {
                throw new Error(`Failed to create named PEM: ${error.message}`);
            }
        } else if (pemValue.type === 'inline') {
            // Return the inline data directly
            return pemValue.data;
        } else if (pemValue.type === 'reference') {
            // Return the reference name
            return pemValue.name;
        }
        return null;
    }

    // Server Management
    openServerModal(bindLocation = null) {
        const modal = document.getElementById('server-modal');
        const title = document.getElementById('server-modal-title');
        const form = document.getElementById('server-form');
        
        this.currentEditingId = bindLocation;
        this.currentEditingType = 'server';
        
        if (bindLocation) {
            title.textContent = 'Edit Server Configuration';
            const server = this.configs.servers.find(s => this.getServerBindLocationString(s) === decodeURIComponent(bindLocation));
            if (server) {
                this.populateServerForm(server);
            }
        } else {
            title.textContent = 'Add Server Configuration';
            form.reset();
            this.resetServerForm();
        }
        
        modal.classList.add('active');
        this.updateTransportSettings();
        this.updateProtocolFields();
        this.updateQuicPemFields();
    }

    populateServerForm(server) {
        const bindLocation = server.bind_location || { type: 'address', value: server.bindLocation };
        
        document.getElementById('server-bind-type').value = bindLocation.type;
        document.getElementById('server-bind-location').value = bindLocation.value;
        document.getElementById('server-transport').value = server.transport || 'tcp';
        document.getElementById('server-protocol-type').value = server.protocol.type;
        
        // Populate protocol-specific fields
        this.updateProtocolFields();
        this.populateProtocolFields(server.protocol);
        
        // Populate transport settings
        if (server.tcp_settings) {
            document.querySelector('[name="tcpNoDelay"]').checked = server.tcp_settings.no_delay !== false;
        }
        
        if (server.quic_settings) {
            // Update PEM field selections
            this.updateQuicPemFields();
            if (server.quic_settings.cert) {
                const certSelect = document.getElementById('server-quic-cert');
                if (certSelect) {
                    certSelect.value = server.quic_settings.cert;
                }
            }
            if (server.quic_settings.key) {
                const keySelect = document.getElementById('server-quic-key');
                if (keySelect) {
                    keySelect.value = server.quic_settings.key;
                }
            }
            document.getElementById('server-quic-alpn').value = 
                Array.isArray(server.quic_settings.alpn_protocols) ? 
                server.quic_settings.alpn_protocols.join(',') : (server.quic_settings.alpn_protocols || '');
            document.getElementById('server-quic-endpoints').value = server.quic_settings.num_endpoints || 0;
            document.getElementById('server-quic-fingerprints').value = 
                Array.isArray(server.quic_settings.client_fingerprints) ? 
                server.quic_settings.client_fingerprints.join('\n') : (server.quic_settings.client_fingerprints || '');
        }
        
        document.getElementById('server-rules').value = server.rules && server.rules.length > 0 ? server.rules[0] : '';
    }

    resetServerForm() {
        document.getElementById('server-bind-type').value = 'address';
        document.getElementById('server-transport').value = 'tcp';
        document.getElementById('server-protocol-type').value = '';
        document.querySelector('[name="tcpNoDelay"]').checked = true;
        this.updateBindLocationPlaceholder();
    }

    updateQuicPemFields() {
        const certField = document.getElementById('quic-cert-field');
        const keyField = document.getElementById('quic-key-field');
        
        if (certField) {
            certField.innerHTML = this.createPemFieldHTML('server-quic-cert', 'quicCert', true);
        }
        if (keyField) {
            keyField.innerHTML = this.createPemFieldHTML('server-quic-key', 'quicKey', true);
        }
    }

    updateBindLocationPlaceholder() {
        const bindType = document.getElementById('server-bind-type').value;
        const bindLocation = document.getElementById('server-bind-location');
        
        if (bindType === 'address') {
            bindLocation.placeholder = '0.0.0.0:8080';
        } else {
            bindLocation.placeholder = '/tmp/shoes.sock';
        }
    }

    updateTransportSettings() {
        const transport = document.getElementById('server-transport').value;
        const tcpSettings = document.getElementById('tcp-settings');
        const quicSettings = document.getElementById('quic-settings');
        
        if (transport === 'tcp') {
            tcpSettings.style.display = 'block';
            quicSettings.style.display = 'none';
        } else if (transport === 'quic') {
            tcpSettings.style.display = 'none';
            quicSettings.style.display = 'block';
        } else {
            tcpSettings.style.display = 'none';
            quicSettings.style.display = 'none';
        }

        // Unix socket only available for TCP
        const bindType = document.getElementById('server-bind-type');
        if (transport !== 'tcp' && bindType.value === 'path') {
            bindType.value = 'address';
            this.updateBindLocationPlaceholder();
        }
    }

    updateProtocolFields() {
        const protocolType = document.getElementById('server-protocol-type').value;
        const fieldsContainer = document.getElementById('protocol-fields');
        
        fieldsContainer.innerHTML = this.getProtocolFields(protocolType);
    }

    getProtocolFields(type) {
        const fields = {
            'http': `
                <div class="form-grid">
                    <div class="form-group">
                        <label for="protocol-username">Username (Optional)</label>
                        <input type="text" id="protocol-username" name="protocolUsername" 
                               placeholder="username">
                    </div>
                    <div class="form-group">
                        <label for="protocol-password">Password (Optional)</label>
                        <input type="password" id="protocol-password" name="protocolPassword" 
                               placeholder="password">
                    </div>
                </div>
            `,
            'socks': `
                <div class="form-grid">
                    <div class="form-group">
                        <label for="protocol-username">Username (Optional)</label>
                        <input type="text" id="protocol-username" name="protocolUsername" 
                               placeholder="username">
                    </div>
                    <div class="form-group">
                        <label for="protocol-password">Password (Optional)</label>
                        <input type="password" id="protocol-password" name="protocolPassword" 
                               placeholder="password">
                    </div>
                </div>
            `,
            'shadowsocks': `
                <div class="form-grid">
                    <div class="form-group">
                        <label for="protocol-cipher">Cipher</label>
                        <select id="protocol-cipher" name="protocolCipher" required>
                            <option value="">Select Cipher</option>
                            <option value="aes-256-gcm">AES-256-GCM</option>
                            <option value="aes-128-gcm">AES-128-GCM</option>
                            <option value="chacha20-ietf-poly1305">ChaCha20-IETF-Poly1305</option>
                            <option value="2022-blake3-aes-256-gcm">2022-blake3-aes-256-gcm</option>
                            <option value="2022-blake3-chacha20-poly1305">2022-blake3-chacha20-poly1305</option>
                        </select>
                    </div>
                    <div class="form-group">
                        <label for="protocol-password">Password</label>
                        <input type="password" id="protocol-password" name="protocolPassword" 
                               placeholder="password" required>
                    </div>
                </div>
            `,
            'snell': `
                <div class="form-grid">
                    <div class="form-group">
                        <label for="protocol-cipher">Cipher</label>
                        <select id="protocol-cipher" name="protocolCipher" required>
                            <option value="">Select Cipher</option>
                            <option value="aes-256-gcm">AES-256-GCM</option>
                            <option value="aes-128-gcm">AES-128-GCM</option>
                            <option value="chacha20-ietf-poly1305">ChaCha20-IETF-Poly1305</option>
                        </select>
                    </div>
                    <div class="form-group">
                        <label for="protocol-password">Password</label>
                        <input type="password" id="protocol-password" name="protocolPassword" 
                               placeholder="password" required>
                    </div>
                    <div class="form-group">
                        <label class="checkbox-label">
                            <input type="checkbox" name="protocolUdpEnabled" checked>
                            <span class="checkmark"></span>
                            UDP Enabled
                        </label>
                    </div>
                    <div class="form-group">
                        <label for="protocol-udp-sockets">UDP Sockets</label>
                        <input type="number" id="protocol-udp-sockets" name="protocolUdpSockets" 
                               value="1" min="1">
                    </div>
                </div>
            `,
            'vless': `
                <div class="form-grid">
                    <div class="form-group">
                        <label for="protocol-user-id">User ID (UUID)</label>
                        <input type="text" id="protocol-user-id" name="protocolUserId" 
                               placeholder="123e4567-e89b-12d3-a456-426614174000" required>
                        <small class="form-hint">Generate a UUID for the user ID</small>
                    </div>
                    <div class="form-group">
                        <label class="checkbox-label">
                            <input type="checkbox" name="protocolUdpEnabled" checked>
                            <span class="checkmark"></span>
                            UDP Enabled
                        </label>
                    </div>
                </div>
            `,
            'trojan': `
                <div class="form-grid">
                    <div class="form-group">
                        <label for="protocol-password">Password</label>
                        <input type="password" id="protocol-password" name="protocolPassword" 
                               placeholder="password" required>
                    </div>
                </div>
                <div class="form-group">
                    <label class="checkbox-label">
                        <input type="checkbox" name="protocolShadowsocksEnabled">
                        <span class="checkmark"></span>
                        Enable Additional Shadowsocks Encryption
                    </label>
                </div>
                <div id="trojan-shadowsocks" class="form-grid" style="display: none;">
                    <div class="form-group">
                        <label for="protocol-ss-cipher">Shadowsocks Cipher</label>
                        <select id="protocol-ss-cipher" name="protocolSsCipher">
                            <option value="aes-256-gcm">AES-256-GCM</option>
                            <option value="chacha20-ietf-poly1305">ChaCha20-IETF-Poly1305</option>
                        </select>
                    </div>
                    <div class="form-group">
                        <label for="protocol-ss-password">Shadowsocks Password</label>
                        <input type="password" id="protocol-ss-password" name="protocolSsPassword" 
                               placeholder="shadowsocks password">
                    </div>
                </div>
            `,
            'vmess': `
                <div class="form-grid">
                    <div class="form-group">
                        <label for="protocol-cipher">Cipher</label>
                        <select id="protocol-cipher" name="protocolCipher" required>
                            <option value="auto">Auto</option>
                            <option value="aes-128-gcm">AES-128-GCM</option>
                            <option value="chacha20-poly1305">ChaCha20-Poly1305</option>
                            <option value="none">None</option>
                        </select>
                    </div>
                    <div class="form-group">
                        <label for="protocol-user-id">User ID (UUID)</label>
                        <input type="text" id="protocol-user-id" name="protocolUserId" 
                               placeholder="123e4567-e89b-12d3-a456-426614174000" required>
                    </div>
                    <div class="form-group">
                        <label class="checkbox-label">
                            <input type="checkbox" name="protocolForceAead" checked>
                            <span class="checkmark"></span>
                            Force AEAD
                        </label>
                    </div>
                    <div class="form-group">
                        <label class="checkbox-label">
                            <input type="checkbox" name="protocolUdpEnabled" checked>
                            <span class="checkmark"></span>
                            UDP Enabled
                        </label>
                    </div>
                </div>
            `,
            'forward': `
                <div class="form-group">
                    <label for="protocol-targets">Target Addresses</label>
                    <textarea id="protocol-targets" name="protocolTargets" 
                              placeholder="target1.example.com:80\ntarget2.example.com:443" required></textarea>
                    <small class="form-hint">One target address per line</small>
                </div>
            `,
            'hysteria2': `
                <div class="form-grid">
                    <div class="form-group">
                        <label for="protocol-password">Password</label>
                        <input type="password" id="protocol-password" name="protocolPassword" 
                               placeholder="password" required>
                    </div>
                    <div class="form-group">
                        <label class="checkbox-label">
                            <input type="checkbox" name="protocolUdpEnabled" checked>
                            <span class="checkmark"></span>
                            UDP Enabled
                        </label>
                    </div>
                </div>
            `,
            'tuicv5': `
                <div class="form-grid">
                    <div class="form-group">
                        <label for="protocol-uuid">UUID</label>
                        <input type="text" id="protocol-uuid" name="protocolUuid" 
                               placeholder="123e4567-e89b-12d3-a456-426614174000" required>
                    </div>
                    <div class="form-group">
                        <label for="protocol-password">Password</label>
                        <input type="password" id="protocol-password" name="protocolPassword" 
                               placeholder="password" required>
                    </div>
                </div>
            `,
            'tls': `
                <div class="form-grid">
                    <div class="form-group">
                        <label for="protocol-cert">Certificate <span class="required">*</span></label>
                        ${this.createPemFieldHTML('protocol-cert', 'protocolCert', true)}
                    </div>
                    <div class="form-group">
                        <label for="protocol-key">Private Key <span class="required">*</span></label>
                        ${this.createPemFieldHTML('protocol-key', 'protocolKey', true)}
                    </div>
                </div>
                <div class="form-group">
                    <label for="protocol-alpn">ALPN Protocols</label>
                    <input type="text" id="protocol-alpn" name="protocolAlpn" 
                           placeholder="h2, http/1.1 (comma-separated)">
                </div>
            `,
            'websocket': `
                <div class="form-group">
                    <label for="protocol-path">WebSocket Path</label>
                    <input type="text" id="protocol-path" name="protocolPath" 
                           placeholder="/ws" value="/ws">
                </div>
                <div class="form-group">
                    <label for="protocol-headers">Custom Headers (Optional)</label>
                    <textarea id="protocol-headers" name="protocolHeaders" 
                              placeholder="Header-Name: Header-Value\nAnother-Header: Another-Value"></textarea>
                    <small class="form-hint">One header per line in format: Header-Name: Header-Value</small>
                </div>
            `
        };

        const html = fields[type] || '';
        
        // Add event listeners for dynamic fields
        setTimeout(() => {
            if (type === 'trojan') {
                const ssEnabledCheckbox = document.querySelector('[name="protocolShadowsocksEnabled"]');
                const ssFields = document.getElementById('trojan-shadowsocks');
                if (ssEnabledCheckbox) {
                    ssEnabledCheckbox.addEventListener('change', () => {
                        ssFields.style.display = ssEnabledCheckbox.checked ? 'grid' : 'none';
                    });
                }
            }
        }, 0);

        return html;
    }

    populateProtocolFields(protocol) {
        // Populate common fields
        const usernameField = document.getElementById('protocol-username');
        const passwordField = document.getElementById('protocol-password');
        const cipherField = document.getElementById('protocol-cipher');
        const userIdField = document.getElementById('protocol-user-id');

        if (usernameField && protocol.username) {
            usernameField.value = protocol.username;
        }
        if (passwordField && protocol.password) {
            passwordField.value = protocol.password;
        }
        if (cipherField && protocol.cipher) {
            cipherField.value = protocol.cipher;
        }
        if (userIdField && protocol.user_id) {
            userIdField.value = protocol.user_id;
        }

        // Populate checkboxes
        const udpEnabledField = document.querySelector('[name="protocolUdpEnabled"]');
        if (udpEnabledField && protocol.hasOwnProperty('udp_enabled')) {
            udpEnabledField.checked = protocol.udp_enabled;
        }

        const forceAeadField = document.querySelector('[name="protocolForceAead"]');
        if (forceAeadField && protocol.hasOwnProperty('force_aead')) {
            forceAeadField.checked = protocol.force_aead;
        }

        // Handle protocol-specific fields
        if (protocol.type === 'snell' && protocol.udp_num_sockets) {
            const udpSocketsField = document.getElementById('protocol-udp-sockets');
            if (udpSocketsField) {
                udpSocketsField.value = protocol.udp_num_sockets;
            }
        }

        if (protocol.type === 'trojan' && protocol.shadowsocks) {
            const ssEnabledField = document.querySelector('[name="protocolShadowsocksEnabled"]');
            if (ssEnabledField) {
                ssEnabledField.checked = true;
                ssEnabledField.dispatchEvent(new Event('change'));
                
                const ssCipherField = document.getElementById('protocol-ss-cipher');
                const ssPasswordField = document.getElementById('protocol-ss-password');
                if (ssCipherField) ssCipherField.value = protocol.shadowsocks.cipher;
                if (ssPasswordField) ssPasswordField.value = protocol.shadowsocks.password;
            }
        }

        if (protocol.type === 'forward' && protocol.targets) {
            const targetsField = document.getElementById('protocol-targets');
            if (targetsField) {
                targetsField.value = Array.isArray(protocol.targets) ? 
                    protocol.targets.join('\n') : protocol.targets;
            }
        }

        if (protocol.type === 'tuicv5' && protocol.uuid) {
            const uuidField = document.getElementById('protocol-uuid');
            if (uuidField) {
                uuidField.value = protocol.uuid;
            }
        }

        if (protocol.type === 'tls') {
            const certField = document.getElementById('protocol-cert');
            const keyField = document.getElementById('protocol-key');
            const alpnField = document.getElementById('protocol-alpn');
            
            if (certField && protocol.cert) {
                // Check if it's inline PEM data
                if (protocol.cert.includes('-----BEGIN')) {
                    certField.value = '__inline__';
                    this.handlePemSelectChange('protocol-cert');
                    const inlineField = document.getElementById('protocol-cert-inline');
                    if (inlineField) inlineField.value = protocol.cert;
                } else {
                    certField.value = protocol.cert;
                }
            }
            if (keyField && protocol.key) {
                // Check if it's inline PEM data
                if (protocol.key.includes('-----BEGIN')) {
                    keyField.value = '__inline__';
                    this.handlePemSelectChange('protocol-key');
                    const inlineField = document.getElementById('protocol-key-inline');
                    if (inlineField) inlineField.value = protocol.key;
                } else {
                    keyField.value = protocol.key;
                }
            }
            if (alpnField && protocol.alpn_protocols) {
                alpnField.value = Array.isArray(protocol.alpn_protocols) ?
                    protocol.alpn_protocols.join(', ') : protocol.alpn_protocols;
            }
        }

        if (protocol.type === 'websocket') {
            const pathField = document.getElementById('protocol-path');
            const headersField = document.getElementById('protocol-headers');
            
            if (pathField && protocol.path) pathField.value = protocol.path;
            if (headersField && protocol.headers) {
                const headerText = Object.entries(protocol.headers)
                    .map(([k, v]) => `${k}: ${v}`)
                    .join('\n');
                headersField.value = headerText;
            }
        }
    }

    async saveServerConfig() {
        const form = document.getElementById('server-form');
        const formData = new FormData(form);
        
        try {
            const serverConfig = this.buildServerConfig(formData);
            
            // Convert to API format
            const apiServer = this.serverToApiFormat(serverConfig);
            
            if (this.currentEditingId) {
                // Update existing server
                await this.apiCall('PUT', `/servers/${this.currentEditingId}`, apiServer);
                this.showToast('success', 'Server configuration updated successfully');
            } else {
                // Add new server
                await this.apiCall('POST', '/servers', apiServer);
                this.showToast('success', 'Server configuration created successfully');
            }
            
            this.closeModals();
            await this.loadConfiguration(); // Reload to get latest data
            
        } catch (error) {
            this.showToast('error', `Error saving configuration: ${error.message}`);
        }
    }
    
    serverToApiFormat(server) {
        const apiServer = {
            bind_location: {
                type: server.bindType,
                value: server.bindLocation
            },
            protocol: server.protocol,
            transport: server.transport
        };
        
        if (server.tcpSettings) {
            apiServer.tcp_settings = {
                no_delay: server.tcpSettings.noDelay
            };
        }
        
        if (server.quicSettings) {
            apiServer.quic_settings = {
                cert: server.quicSettings.cert,
                key: server.quicSettings.key,
                num_endpoints: server.quicSettings.numEndpoints || 0
            };
            
            if (server.quicSettings.alpnProtocols) {
                apiServer.quic_settings.alpn_protocols = server.quicSettings.alpnProtocols;
            }
            
            if (server.quicSettings.clientFingerprints) {
                apiServer.quic_settings.client_fingerprints = server.quicSettings.clientFingerprints;
            }
        }
        
        if (server.rules) {
            apiServer.rules = [server.rules];
        }
        
        return apiServer;
    }

    buildServerConfig(formData) {
        const config = {
            bindType: formData.get('bindType'),
            bindLocation: formData.get('bindLocation'),
            transport: formData.get('transport') || 'tcp',
            protocol: await this.buildProtocolConfig(formData),
            rules: formData.get('rules') || null
        };

        // Validate bind location
        if (!config.bindLocation) {
            throw new Error('Bind location is required');
        }

        // Add transport settings
        if (config.transport === 'tcp') {
            config.tcpSettings = {
                noDelay: formData.get('tcpNoDelay') === 'on'
            };
        } else if (config.transport === 'quic') {
            // Handle PEM fields
            const certValue = await this.processPemField('server-quic-cert');
            const keyValue = await this.processPemField('server-quic-key');
            
            if (!certValue || !keyValue) {
                throw new Error('QUIC transport requires certificate and key');
            }
            
            config.quicSettings = {
                cert: certValue,
                key: keyValue,
                numEndpoints: parseInt(formData.get('quicEndpoints')) || 0
            };

            const alpn = formData.get('quicAlpn');
            if (alpn) {
                config.quicSettings.alpnProtocols = alpn.split(',').map(s => s.trim()).filter(s => s);
            }

            const fingerprints = formData.get('quicFingerprints');
            if (fingerprints) {
                config.quicSettings.clientFingerprints = fingerprints.split('\n').map(s => s.trim()).filter(s => s);
            }
        }

        // Unix socket validation
        if (config.bindType === 'path' && config.transport !== 'tcp') {
            throw new Error('Unix domain socket is only supported with TCP transport');
        }

        return config;
    }

    async buildProtocolConfig(formData) {
        const type = formData.get('protocolType');
        if (!type) {
            throw new Error('Protocol type is required');
        }

        const config = { type };

        switch (type) {
            case 'http':
            case 'socks':
                const username = formData.get('protocolUsername');
                const password = formData.get('protocolPassword');
                if (username) config.username = username;
                if (password) config.password = password;
                break;

            case 'shadowsocks':
                config.cipher = formData.get('protocolCipher');
                config.password = formData.get('protocolPassword');
                if (!config.cipher || !config.password) {
                    throw new Error('Shadowsocks requires cipher and password');
                }
                break;

            case 'snell':
                config.cipher = formData.get('protocolCipher');
                config.password = formData.get('protocolPassword');
                config.udp_enabled = formData.get('protocolUdpEnabled') === 'on';
                config.udp_num_sockets = parseInt(formData.get('protocolUdpSockets')) || 1;
                if (!config.cipher || !config.password) {
                    throw new Error('Snell requires cipher and password');
                }
                break;

            case 'vless':
                config.user_id = formData.get('protocolUserId');
                config.udp_enabled = formData.get('protocolUdpEnabled') === 'on';
                if (!config.user_id) {
                    throw new Error('VLESS requires user ID');
                }
                if (!this.isValidUUID(config.user_id)) {
                    throw new Error('Invalid UUID format for user ID');
                }
                break;

            case 'trojan':
                config.password = formData.get('protocolPassword');
                if (!config.password) {
                    throw new Error('Trojan requires password');
                }
                
                if (formData.get('protocolShadowsocksEnabled') === 'on') {
                    const ssCipher = formData.get('protocolSsCipher');
                    const ssPassword = formData.get('protocolSsPassword');
                    if (ssCipher && ssPassword) {
                        config.shadowsocks = {
                            cipher: ssCipher,
                            password: ssPassword
                        };
                    }
                }
                break;

            case 'vmess':
                config.cipher = formData.get('protocolCipher');
                config.user_id = formData.get('protocolUserId');
                config.force_aead = formData.get('protocolForceAead') === 'on';
                config.udp_enabled = formData.get('protocolUdpEnabled') === 'on';
                if (!config.cipher || !config.user_id) {
                    throw new Error('VMess requires cipher and user ID');
                }
                if (!this.isValidUUID(config.user_id)) {
                    throw new Error('Invalid UUID format for user ID');
                }
                break;

            case 'forward':
                const targets = formData.get('protocolTargets');
                if (!targets) {
                    throw new Error('Port forward requires target addresses');
                }
                config.targets = targets.split('\n').map(s => s.trim()).filter(s => s);
                break;

            case 'hysteria2':
                config.password = formData.get('protocolPassword');
                config.udp_enabled = formData.get('protocolUdpEnabled') === 'on';
                if (!config.password) {
                    throw new Error('Hysteria2 requires password');
                }
                break;

            case 'tuicv5':
                config.uuid = formData.get('protocolUuid');
                config.password = formData.get('protocolPassword');
                if (!config.uuid || !config.password) {
                    throw new Error('TuicV5 requires UUID and password');
                }
                if (!this.isValidUUID(config.uuid)) {
                    throw new Error('Invalid UUID format');
                }
                break;

            case 'tls':
                // Handle PEM fields
                config.cert = await this.processPemField('protocol-cert');
                config.key = await this.processPemField('protocol-key');
                if (!config.cert || !config.key) {
                    throw new Error('TLS requires certificate and key');
                }
                const alpn = formData.get('protocolAlpn');
                if (alpn) {
                    config.alpn_protocols = alpn.split(',').map(s => s.trim()).filter(s => s);
                }
                break;

            case 'websocket':
                config.path = formData.get('protocolPath') || '/ws';
                const headers = formData.get('protocolHeaders');
                if (headers) {
                    config.headers = {};
                    headers.split('\n').forEach(line => {
                        const [key, ...valueParts] = line.split(':');
                        if (key && valueParts.length > 0) {
                            config.headers[key.trim()] = valueParts.join(':').trim();
                        }
                    });
                }
                break;

            default:
                throw new Error(`Unknown protocol type: ${type}`);
        }

        return config;
    }

    editServer(bindLocation) {
        this.openServerModal(bindLocation);
    }

    async duplicateServer(bindLocation) {
        const decodedLocation = decodeURIComponent(bindLocation);
        const server = this.configs.servers.find(s => this.getServerBindLocationString(s) === decodedLocation);
        if (server) {
            const copy = JSON.parse(JSON.stringify(server));
            
            // Modify bind location to avoid conflicts
            const bindLoc = copy.bind_location || { type: 'address', value: copy.bindLocation };
            if (bindLoc.type === 'address') {
                const match = bindLoc.value.match(/^(.+):(\d+)$/);
                if (match) {
                    const newPort = parseInt(match[2]) + 1;
                    bindLoc.value = `${match[1]}:${newPort}`;
                }
            } else {
                bindLoc.value += '.copy';
            }
            copy.bind_location = bindLoc;
            
            try {
                await this.apiCall('POST', '/servers', copy);
                await this.loadConfiguration();
                this.showToast('success', 'Server configuration duplicated');
            } catch (error) {
                this.showToast('error', `Failed to duplicate server: ${error.message}`);
            }
        }
    }

    async deleteServer(bindLocation) {
        const decodedLocation = decodeURIComponent(bindLocation);
        if (confirm(`Are you sure you want to delete the server at ${decodedLocation}?`)) {
            try {
                await this.apiCall('DELETE', `/servers/${bindLocation}`);
                await this.loadConfiguration();
                this.showToast('success', 'Server configuration deleted');
            } catch (error) {
                this.showToast('error', `Failed to delete server: ${error.message}`);
            }
        }
    }

    // Client Group Management
    openClientGroupModal(groupName = null) {
        const modal = document.getElementById('client-group-modal');
        const title = document.getElementById('client-group-modal-title');
        const form = document.getElementById('client-group-form');
        
        this.currentEditingId = groupName;
        this.currentEditingType = 'client-group';
        
        if (groupName) {
            title.textContent = 'Edit Client Group';
            const group = this.configs.clientGroups.find(g => g.id === groupName);
            if (group) {
                this.populateClientGroupForm(group);
            }
        } else {
            title.textContent = 'Add Client Group';
            form.reset();
            this.resetClientGroupForm();
        }
        
        modal.classList.add('active');
    }

    populateClientGroupForm(group) {
        document.getElementById('client-group-name').value = group.name;
        
        // Clear existing proxies
        const container = document.getElementById('client-proxies-list');
        container.innerHTML = '';
        
        // Add existing proxies
        group.proxies.forEach((proxy, index) => {
            this.addClientProxyToForm(proxy, index);
        });
    }

    resetClientGroupForm() {
        const container = document.getElementById('client-proxies-list');
        container.innerHTML = '';
        // Add one default proxy
        this.addClientProxyToForm();
    }

    addClientProxyToForm(proxy = null, index = null) {
        const container = document.getElementById('client-proxies-list');
        const proxyIndex = index !== null ? index : container.children.length;
        
        const proxyDiv = document.createElement('div');
        proxyDiv.className = 'dynamic-item';
        proxyDiv.innerHTML = `
            <div class="dynamic-item-header">
                <span class="dynamic-item-title">Client Proxy #${proxyIndex + 1}</span>
                <button type="button" class="remove-item" onclick="this.parentElement.parentElement.remove()">
                    <i class="fas fa-times"></i>
                </button>
            </div>
            <div class="form-grid">
                <div class="form-group">
                    <label>Protocol Type</label>
                    <select name="clientProtocolType_${proxyIndex}" onchange="app.updateClientProtocolFields(${proxyIndex})" required>
                        <option value="">Select Protocol</option>
                        <option value="direct">Direct</option>
                        <option value="http">HTTP Proxy</option>
                        <option value="socks">SOCKS5 Proxy</option>
                        <option value="shadowsocks">Shadowsocks</option>
                        <option value="snell">Snell</option>
                        <option value="vless">VLESS</option>
                        <option value="trojan">Trojan</option>
                        <option value="vmess">VMess</option>
                    </select>
                </div>
                <div class="form-group">
                    <label>Address</label>
                    <input type="text" name="clientAddress_${proxyIndex}" placeholder="example.com:8080 or unspecified">
                </div>
                <div class="form-group">
                    <label>Transport</label>
                    <select name="clientTransport_${proxyIndex}">
                        <option value="tcp">TCP</option>
                        <option value="quic">QUIC</option>
                        <option value="udp">UDP</option>
                    </select>
                </div>
                <div class="form-group">
                    <label>Bind Interface (Optional)</label>
                    <input type="text" name="clientInterface_${proxyIndex}" placeholder="eth0">
                    <small class="form-hint">Linux/Android/Fuchsia only</small>
                </div>
            </div>
            <div id="client-protocol-fields-${proxyIndex}" class="form-section">
                <!-- Dynamic protocol fields -->
            </div>
        `;
        
        container.appendChild(proxyDiv);
        
        // Populate if editing
        if (proxy) {
            const protocolSelect = proxyDiv.querySelector(`[name="clientProtocolType_${proxyIndex}"]`);
            const addressInput = proxyDiv.querySelector(`[name="clientAddress_${proxyIndex}"]`);
            const transportSelect = proxyDiv.querySelector(`[name="clientTransport_${proxyIndex}"]`);
            const interfaceInput = proxyDiv.querySelector(`[name="clientInterface_${proxyIndex}"]`);
            
            protocolSelect.value = proxy.protocol.type;
            addressInput.value = proxy.address || '';
            transportSelect.value = proxy.transport || 'tcp';
            if (proxy.bind_interface) {
                interfaceInput.value = proxy.bind_interface;
            }
            
            this.updateClientProtocolFields(proxyIndex);
            setTimeout(() => {
                this.populateClientProtocolFields(proxy.protocol, proxyIndex);
            }, 0);
        }
    }

    updateClientProtocolFields(proxyIndex) {
        const protocolSelect = document.querySelector(`[name="clientProtocolType_${proxyIndex}"]`);
        const fieldsContainer = document.getElementById(`client-protocol-fields-${proxyIndex}`);
        
        if (!protocolSelect || !fieldsContainer) return;
        
        const protocolType = protocolSelect.value;
        fieldsContainer.innerHTML = this.getClientProtocolFields(protocolType, proxyIndex);
    }

    getClientProtocolFields(type, index) {
        const fields = {
            'direct': '',
            'http': `
                <h5>HTTP Proxy Settings</h5>
                <div class="form-grid">
                    <div class="form-group">
                        <label>Username (Optional)</label>
                        <input type="text" name="clientUsername_${index}" placeholder="username">
                    </div>
                    <div class="form-group">
                        <label>Password (Optional)</label>
                        <input type="password" name="clientPassword_${index}" placeholder="password">
                    </div>
                </div>
            `,
            'socks': `
                <h5>SOCKS5 Proxy Settings</h5>
                <div class="form-grid">
                    <div class="form-group">
                        <label>Username (Optional)</label>
                        <input type="text" name="clientUsername_${index}" placeholder="username">
                    </div>
                    <div class="form-group">
                        <label>Password (Optional)</label>
                        <input type="password" name="clientPassword_${index}" placeholder="password">
                    </div>
                </div>
            `,
            'shadowsocks': `
                <h5>Shadowsocks Settings</h5>
                <div class="form-grid">
                    <div class="form-group">
                        <label>Cipher</label>
                        <select name="clientCipher_${index}" required>
                            <option value="">Select Cipher</option>
                            <option value="aes-256-gcm">AES-256-GCM</option>
                            <option value="aes-128-gcm">AES-128-GCM</option>
                            <option value="chacha20-ietf-poly1305">ChaCha20-IETF-Poly1305</option>
                            <option value="2022-blake3-aes-256-gcm">2022-blake3-aes-256-gcm</option>
                        </select>
                    </div>
                    <div class="form-group">
                        <label>Password</label>
                        <input type="password" name="clientPassword_${index}" placeholder="password" required>
                    </div>
                </div>
            `,
            'snell': `
                <h5>Snell Settings</h5>
                <div class="form-grid">
                    <div class="form-group">
                        <label>Cipher</label>
                        <select name="clientCipher_${index}" required>
                            <option value="aes-256-gcm">AES-256-GCM</option>
                            <option value="chacha20-ietf-poly1305">ChaCha20-IETF-Poly1305</option>
                        </select>
                    </div>
                    <div class="form-group">
                        <label>Password</label>
                        <input type="password" name="clientPassword_${index}" placeholder="password" required>
                    </div>
                </div>
            `,
            'vless': `
                <h5>VLESS Settings</h5>
                <div class="form-group">
                    <label>User ID (UUID)</label>
                    <input type="text" name="clientUserId_${index}" placeholder="123e4567-e89b-12d3-a456-426614174000" required>
                </div>
            `,
            'trojan': `
                <h5>Trojan Settings</h5>
                <div class="form-grid">
                    <div class="form-group">
                        <label>Password</label>
                        <input type="password" name="clientPassword_${index}" placeholder="password" required>
                    </div>
                </div>
                <div class="form-group">
                    <label class="checkbox-label">
                        <input type="checkbox" name="clientShadowsocksEnabled_${index}">
                        <span class="checkmark"></span>
                        Enable Additional Shadowsocks Encryption
                    </label>
                </div>
                <div id="client-trojan-ss-${index}" class="form-grid" style="display: none;">
                    <div class="form-group">
                        <label>Shadowsocks Cipher</label>
                        <select name="clientSsCipher_${index}">
                            <option value="aes-256-gcm">AES-256-GCM</option>
                            <option value="chacha20-ietf-poly1305">ChaCha20-IETF-Poly1305</option>
                        </select>
                    </div>
                    <div class="form-group">
                        <label>Shadowsocks Password</label>
                        <input type="password" name="clientSsPassword_${index}" placeholder="password">
                    </div>
                </div>
            `,
            'vmess': `
                <h5>VMess Settings</h5>
                <div class="form-grid">
                    <div class="form-group">
                        <label>Cipher</label>
                        <select name="clientCipher_${index}" required>
                            <option value="auto">Auto</option>
                            <option value="aes-128-gcm">AES-128-GCM</option>
                            <option value="chacha20-poly1305">ChaCha20-Poly1305</option>
                            <option value="none">None</option>
                        </select>
                    </div>
                    <div class="form-group">
                        <label>User ID (UUID)</label>
                        <input type="text" name="clientUserId_${index}" placeholder="123e4567-e89b-12d3-a456-426614174000" required>
                    </div>
                    <div class="form-group">
                        <label class="checkbox-label">
                            <input type="checkbox" name="clientAead_${index}" checked>
                            <span class="checkmark"></span>
                            AEAD Enabled
                        </label>
                    </div>
                </div>
            `
        };

        const html = fields[type] || '';
        
        // Add event listeners for dynamic fields
        setTimeout(() => {
            if (type === 'trojan') {
                const ssCheckbox = document.querySelector(`[name="clientShadowsocksEnabled_${index}"]`);
                const ssFields = document.getElementById(`client-trojan-ss-${index}`);
                if (ssCheckbox && ssFields) {
                    ssCheckbox.addEventListener('change', () => {
                        ssFields.style.display = ssCheckbox.checked ? 'grid' : 'none';
                    });
                }
            }
        }, 0);

        return html;
    }

    populateClientProtocolFields(protocol, index) {
        // Populate basic fields
        const usernameField = document.querySelector(`[name="clientUsername_${index}"]`);
        const passwordField = document.querySelector(`[name="clientPassword_${index}"]`);
        const cipherField = document.querySelector(`[name="clientCipher_${index}"]`);
        const userIdField = document.querySelector(`[name="clientUserId_${index}"]`);

        if (usernameField && protocol.username) usernameField.value = protocol.username;
        if (passwordField && protocol.password) passwordField.value = protocol.password;
        if (cipherField && protocol.cipher) cipherField.value = protocol.cipher;
        if (userIdField && protocol.user_id) userIdField.value = protocol.user_id;

        // Populate checkboxes
        const aeadField = document.querySelector(`[name="clientAead_${index}"]`);
        if (aeadField && protocol.hasOwnProperty('aead')) {
            aeadField.checked = protocol.aead;
        }

        // Handle Trojan Shadowsocks
        if (protocol.type === 'trojan' && protocol.shadowsocks) {
            const ssEnabledField = document.querySelector(`[name="clientShadowsocksEnabled_${index}"]`);
            if (ssEnabledField) {
                ssEnabledField.checked = true;
                ssEnabledField.dispatchEvent(new Event('change'));
                
                const ssCipherField = document.querySelector(`[name="clientSsCipher_${index}"]`);
                const ssPasswordField = document.querySelector(`[name="clientSsPassword_${index}"]`);
                if (ssCipherField) ssCipherField.value = protocol.shadowsocks.cipher;
                if (ssPasswordField) ssPasswordField.value = protocol.shadowsocks.password;
            }
        }
    }

    async saveClientGroup() {
        const form = document.getElementById('client-group-form');
        const formData = new FormData(form);
        
        try {
            const groupConfig = this.buildClientGroupConfig(formData);
            
            if (this.currentEditingId) {
                // Update existing group
                await this.apiCall('PUT', `/client-groups/${encodeURIComponent(this.currentEditingId)}`, groupConfig);
                this.showToast('success', 'Client group updated successfully');
            } else {
                // Add new group
                await this.apiCall('POST', '/client-groups', groupConfig);
                this.showToast('success', 'Client group created successfully');
            }
            
            this.closeModals();
            await this.loadConfiguration();
            
        } catch (error) {
            this.showToast('error', `Error saving client group: ${error.message}`);
        }
    }

    buildClientGroupConfig(formData) {
        const name = formData.get('client-group-name');
        if (!name) {
            throw new Error('Group name is required');
        }

        const proxies = [];
        const container = document.getElementById('client-proxies-list');
        
        Array.from(container.children).forEach((proxyDiv, index) => {
            const proxy = this.buildClientProxyConfig(formData, index);
            proxies.push(proxy);
        });

        if (proxies.length === 0) {
            throw new Error('At least one client proxy is required');
        }

        return { name, proxies };
    }

    buildClientProxyConfig(formData, index) {
        const protocolType = formData.get(`clientProtocolType_${index}`);
        if (!protocolType) {
            throw new Error(`Protocol type is required for proxy #${index + 1}`);
        }

        const config = {
            protocol: { type: protocolType },
            address: formData.get(`clientAddress_${index}`) || 'unspecified',
            transport: formData.get(`clientTransport_${index}`) || 'tcp'
        };

        const bindInterface = formData.get(`clientInterface_${index}`);
        if (bindInterface) {
            config.bind_interface = bindInterface;
        }

        // Build protocol-specific config
        switch (protocolType) {
            case 'direct':
                // No additional config needed
                break;
                
            case 'http':
            case 'socks':
                const username = formData.get(`clientUsername_${index}`);
                const password = formData.get(`clientPassword_${index}`);
                if (username) config.protocol.username = username;
                if (password) config.protocol.password = password;
                break;
                
            case 'shadowsocks':
            case 'snell':
                config.protocol.cipher = formData.get(`clientCipher_${index}`);
                config.protocol.password = formData.get(`clientPassword_${index}`);
                if (!config.protocol.cipher || !config.protocol.password) {
                    throw new Error(`${protocolType} requires cipher and password`);
                }
                break;
                
            case 'vless':
                config.protocol.user_id = formData.get(`clientUserId_${index}`);
                if (!config.protocol.user_id) {
                    throw new Error('VLESS requires user ID');
                }
                if (!this.isValidUUID(config.protocol.user_id)) {
                    throw new Error('Invalid UUID format for VLESS user ID');
                }
                break;
                
            case 'vmess':
                config.protocol.cipher = formData.get(`clientCipher_${index}`);
                config.protocol.user_id = formData.get(`clientUserId_${index}`);
                config.protocol.aead = formData.get(`clientAead_${index}`) === 'on';
                if (!config.protocol.cipher || !config.protocol.user_id) {
                    throw new Error('VMess requires cipher and user ID');
                }
                if (!this.isValidUUID(config.protocol.user_id)) {
                    throw new Error('Invalid UUID format for VMess user ID');
                }
                break;
                
            case 'trojan':
                config.protocol.password = formData.get(`clientPassword_${index}`);
                if (!config.protocol.password) {
                    throw new Error('Trojan requires password');
                }
                
                if (formData.get(`clientShadowsocksEnabled_${index}`) === 'on') {
                    const ssCipher = formData.get(`clientSsCipher_${index}`);
                    const ssPassword = formData.get(`clientSsPassword_${index}`);
                    if (ssCipher && ssPassword) {
                        config.protocol.shadowsocks = {
                            cipher: ssCipher,
                            password: ssPassword
                        };
                    }
                }
                break;
        }

        return config;
    }

    editClientGroup(groupName) {
        this.openClientGroupModal(groupName);
    }

    async deleteClientGroup(groupName) {
        const group = this.configs.clientGroups.find(g => g.id === groupName);
        if (!group) return;
        
        if (confirm(`Are you sure you want to delete the client group "${group.name}"?`)) {
            try {
                await this.apiCall('DELETE', `/client-groups/${encodeURIComponent(groupName)}`);
                await this.loadConfiguration();
                this.showToast('success', 'Client group deleted');
            } catch (error) {
                this.showToast('error', `Failed to delete client group: ${error.message}`);
            }
        }
    }

    // Rule Group Management
    openRuleGroupModal(groupName = null) {
        const modal = document.getElementById('rule-group-modal');
        const title = document.getElementById('rule-group-modal-title');
        const form = document.getElementById('rule-group-form');
        
        this.currentEditingId = groupName;
        this.currentEditingType = 'rule-group';
        
        if (groupName) {
            title.textContent = 'Edit Rule Group';
            const group = this.configs.ruleGroups.find(g => g.id === groupName);
            if (group) {
                this.populateRuleGroupForm(group);
            }
        } else {
            title.textContent = 'Add Rule Group';
            form.reset();
            this.resetRuleGroupForm();
        }
        
        modal.classList.add('active');
    }

    populateRuleGroupForm(group) {
        document.getElementById('rule-group-name').value = group.name;
        
        // Clear existing rules
        const container = document.getElementById('rules-list');
        container.innerHTML = '';
        
        // Add existing rules
        group.rules.forEach((rule, index) => {
            this.addRuleToForm(rule, index);
        });
    }

    resetRuleGroupForm() {
        const container = document.getElementById('rules-list');
        container.innerHTML = '';
        // Add one default rule
        this.addRuleToForm();
    }

    addRuleToForm(rule = null, index = null) {
        const container = document.getElementById('rules-list');
        const ruleIndex = index !== null ? index : container.children.length;
        
        const ruleDiv = document.createElement('div');
        ruleDiv.className = 'dynamic-item';
        ruleDiv.innerHTML = `
            <div class="dynamic-item-header">
                <span class="dynamic-item-title">Rule #${ruleIndex + 1}</span>
                <button type="button" class="remove-item" onclick="this.parentElement.parentElement.remove()">
                    <i class="fas fa-times"></i>
                </button>
            </div>
            <div class="form-grid">
                <div class="form-group">
                    <label>IP/CIDR Masks</label>
                    <textarea name="ruleMasks_${ruleIndex}" placeholder="0.0.0.0/0\n192.168.0.0/16\nexample.com" required></textarea>
                    <small class="form-hint">One mask per line. Supports IP/CIDR and hostnames</small>
                </div>
                <div class="form-group">
                    <label>Action</label>
                    <select name="ruleAction_${ruleIndex}" onchange="app.updateRuleActionFields(${ruleIndex})" required>
                        <option value="">Select Action</option>
                        <option value="allow">Allow</option>
                        <option value="block">Block</option>
                    </select>
                </div>
            </div>
            <div id="rule-action-fields-${ruleIndex}" class="form-section">
                <!-- Dynamic action fields -->
            </div>
        `;
        
        container.appendChild(ruleDiv);
        
        // Populate if editing
        if (rule) {
            const masksTextarea = ruleDiv.querySelector(`[name="ruleMasks_${ruleIndex}"]`);
            const actionSelect = ruleDiv.querySelector(`[name="ruleAction_${ruleIndex}"]`);
            
            masksTextarea.value = Array.isArray(rule.masks) ? rule.masks.join('\n') : rule.masks;
            actionSelect.value = rule.action.type || rule.action;
            
            this.updateRuleActionFields(ruleIndex);
            setTimeout(() => {
                this.populateRuleActionFields(rule, ruleIndex);
            }, 0);
        }
    }

    updateRuleActionFields(ruleIndex) {
        const actionSelect = document.querySelector(`[name="ruleAction_${ruleIndex}"]`);
        const fieldsContainer = document.getElementById(`rule-action-fields-${ruleIndex}`);
        
        if (!actionSelect || !fieldsContainer) return;
        
        const action = actionSelect.value;
        
        if (action === 'allow') {
            fieldsContainer.innerHTML = `
                <h5>Allow Action Settings</h5>
                <div class="form-grid">
                    <div class="form-group">
                        <label>Override Address (Optional)</label>
                        <input type="text" name="ruleOverrideAddress_${ruleIndex}" placeholder="proxy.example.com:8080">
                        <small class="form-hint">Redirect connections to this address instead</small>
                    </div>
                    <div class="form-group">
                        <label>Client Proxies</label>
                        <select name="ruleClientProxies_${ruleIndex}" multiple size="4" required>
                            <option value="direct">Direct Connection</option>
                            ${this.configs.clientGroups.filter(g => g.id !== 'direct').map(group => 
                                `<option value="${group.name}">${group.name}</option>`
                            ).join('')}
                        </select>
                        <small class="form-hint">Hold Ctrl/Cmd to select multiple options</small>
                    </div>
                </div>
            `;
        } else if (action === 'block') {
            fieldsContainer.innerHTML = `
                <h5>Block Action</h5>
                <p class="form-hint">All connections matching this rule will be blocked.</p>
            `;
        } else {
            fieldsContainer.innerHTML = '';
        }
    }

    populateRuleActionFields(rule, ruleIndex) {
        if (rule.action.type === 'allow' || rule.action === 'allow') {
            const overrideField = document.querySelector(`[name="ruleOverrideAddress_${ruleIndex}"]`);
            const proxiesField = document.querySelector(`[name="ruleClientProxies_${ruleIndex}"]`);
            
            if (overrideField && rule.action.override_address) {
                overrideField.value = rule.action.override_address;
            }
            
            if (proxiesField && rule.action.client_proxies) {
                Array.from(proxiesField.options).forEach(option => {
                    option.selected = rule.action.client_proxies.includes(option.value);
                });
            }
        }
    }

    async saveRuleGroup() {
        const form = document.getElementById('rule-group-form');
        const formData = new FormData(form);
        
        try {
            const groupConfig = this.buildRuleGroupConfig(formData);
            
            if (this.currentEditingId) {
                // Update existing group
                await this.apiCall('PUT', `/rule-groups/${encodeURIComponent(this.currentEditingId)}`, groupConfig);
                this.showToast('success', 'Rule group updated successfully');
            } else {
                // Add new group
                await this.apiCall('POST', '/rule-groups', groupConfig);
                this.showToast('success', 'Rule group created successfully');
            }
            
            this.closeModals();
            await this.loadConfiguration();
            
        } catch (error) {
            this.showToast('error', `Error saving rule group: ${error.message}`);
        }
    }

    buildRuleGroupConfig(formData) {
        const name = formData.get('rule-group-name');
        if (!name) {
            throw new Error('Group name is required');
        }

        const rules = [];
        const container = document.getElementById('rules-list');
        
        Array.from(container.children).forEach((ruleDiv, index) => {
            const rule = this.buildRuleConfig(formData, index);
            rules.push(rule);
        });

        if (rules.length === 0) {
            throw new Error('At least one rule is required');
        }

        return { name, rules };
    }

    buildRuleConfig(formData, index) {
        const masks = formData.get(`ruleMasks_${index}`);
        const action = formData.get(`ruleAction_${index}`);
        
        if (!masks || !action) {
            throw new Error(`Rule #${index + 1} requires masks and action`);
        }

        const rule = {
            masks: masks.split('\n').map(s => s.trim()).filter(s => s),
            action: { type: action }
        };

        if (rule.masks.length === 0) {
            throw new Error(`Rule #${index + 1} requires at least one mask`);
        }

        if (action === 'allow') {
            const overrideAddress = formData.get(`ruleOverrideAddress_${index}`);
            if (overrideAddress) {
                rule.action.override_address = overrideAddress;
            }
            
            const clientProxiesField = document.querySelector(`[name="ruleClientProxies_${index}"]`);
            if (clientProxiesField) {
                const selectedProxies = Array.from(clientProxiesField.selectedOptions)
                    .map(option => option.value);
                
                if (selectedProxies.length === 0) {
                    throw new Error(`Rule #${index + 1} with allow action requires at least one client proxy`);
                }
                
                rule.action.client_proxies = selectedProxies;
            }
        }

        return rule;
    }

    editRuleGroup(groupName) {
        this.openRuleGroupModal(groupName);
    }

    async deleteRuleGroup(groupName) {
        const group = this.configs.ruleGroups.find(g => g.id === groupName);
        if (!group) return;
        
        if (confirm(`Are you sure you want to delete the rule group "${group.name}"?`)) {
            try {
                await this.apiCall('DELETE', `/rule-groups/${encodeURIComponent(groupName)}`);
                await this.loadConfiguration();
                this.showToast('success', 'Rule group deleted');
            } catch (error) {
                this.showToast('error', `Failed to delete rule group: ${error.message}`);
            }
        }
    }

    // Named PEM Management
    openNamedPemModal(pemName = null) {
        const modal = document.getElementById('named-pem-modal');
        const title = document.getElementById('named-pem-modal-title');
        const form = document.getElementById('named-pem-form');
        
        this.currentEditingId = pemName;
        this.currentEditingType = 'named-pem';
        
        if (pemName) {
            title.textContent = 'Edit Named PEM';
            const pem = this.configs.namedPems.find(p => p.pem === pemName);
            if (pem) {
                document.getElementById('pem-name').value = pem.pem;
                document.getElementById('pem-data').value = pem.data || '';
            }
        } else {
            title.textContent = 'Add Named PEM';
            form.reset();
        }
        
        modal.classList.add('active');
    }

    async saveNamedPem() {
        const form = document.getElementById('named-pem-form');
        const pemName = document.getElementById('pem-name').value.trim();
        const pemData = document.getElementById('pem-data').value.trim();
        
        if (!pemName) {
            this.showToast('error', 'PEM name is required');
            return;
        }
        
        if (!pemData) {
            this.showToast('error', 'PEM data is required');
            return;
        }
        
        const pemConfig = {
            pem: pemName,
            data: pemData
        };
        
        try {
            if (this.currentEditingId) {
                // Update existing PEM
                await this.apiCall('PUT', `/named-pems/${encodeURIComponent(this.currentEditingId)}`, pemConfig);
                this.showToast('success', 'Named PEM updated successfully');
            } else {
                // Add new PEM
                await this.apiCall('POST', '/named-pems', pemConfig);
                this.showToast('success', 'Named PEM created successfully');
            }
            
            this.closeModals();
            await this.loadConfiguration();
            
        } catch (error) {
            this.showToast('error', `Error saving named PEM: ${error.message}`);
        }
    }

    editNamedPem(pemName) {
        this.openNamedPemModal(pemName);
    }

    async deleteNamedPem(pemName) {
        if (confirm(`Are you sure you want to delete the named PEM "${pemName}"?`)) {
            try {
                await this.apiCall('DELETE', `/named-pems/${encodeURIComponent(pemName)}`);
                await this.loadConfiguration();
                this.showToast('success', 'Named PEM deleted');
            } catch (error) {
                this.showToast('error', `Failed to delete named PEM: ${error.message}`);
            }
        }
    }

    // Import/Export functionality
    async exportConfiguration() {
        try {
            const yaml = await this.apiCall('GET', '/export');
            this.downloadYaml(yaml);
        } catch (error) {
            this.showToast('error', `Failed to export configuration: ${error.message}`);
        }
    }

    downloadYaml(yaml) {
        const blob = new Blob([yaml], { type: 'text/yaml' });
        const url = URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = 'shoes-config.yaml';
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
        URL.revokeObjectURL(url);
        this.showToast('success', 'Configuration downloaded');
    }

    async copyConfigurationToClipboard() {
        try {
            const yaml = await this.apiCall('GET', '/export');
            await navigator.clipboard.writeText(yaml);
            this.showToast('success', 'Configuration copied to clipboard');
        } catch (error) {
            this.showToast('error', `Failed to copy to clipboard: ${error.message}`);
        }
    }

    importConfiguration(file) {
        if (!file) return;
        
        const reader = new FileReader();
        reader.onload = async (e) => {
            try {
                const content = e.target.result;
                await this.importYamlConfiguration(content);
                this.showToast('success', 'Configuration imported successfully');
            } catch (error) {
                this.showToast('error', `Import failed: ${error.message}`);
            }
        };
        reader.readAsText(file);
    }

    async importYamlConfiguration(yamlContent) {
        try {
            const result = await this.apiCall('POST', '/import', { yaml: yamlContent });
            if (result.success) {
                await this.loadConfiguration();
            }
        } catch (error) {
            throw new Error(`Failed to import YAML: ${error.message}`);
        }
    }

    async validateConfiguration() {
        try {
            const currentConfig = {
                servers: this.configs.servers,
                client_groups: this.configs.clientGroups.map(g => ({
                    name: g.name,
                    proxies: g.proxies
                })),
                rule_groups: this.configs.ruleGroups.map(g => ({
                    name: g.name,
                    rules: g.rules
                }))
            };
            
            const result = await this.apiCall('POST', '/config/validate', currentConfig);
            const results = [];
            
            if (!result.valid && result.errors) {
                result.errors.forEach(error => {
                    results.push({
                        type: 'error',
                        message: error
                    });
                });
            } else if (result.valid) {
                results.push({
                    type: 'success',
                    message: 'Configuration is valid'
                });
            }
            
            this.displayValidationResults(results);
        } catch (error) {
            this.showToast('error', `Validation failed: ${error.message}`);
        }
    }

    displayValidationResults(results) {
        const container = document.getElementById('validation-results');
        
        if (results.length === 0) {
            container.innerHTML = '';
            return;
        }

        container.innerHTML = results.map(result => `
            <div class="validation-item ${result.type}">
                <i class="fas fa-${result.type === 'error' ? 'exclamation-circle' : 
                                 result.type === 'warning' ? 'exclamation-triangle' : 
                                 'check-circle'}"></i>
                <div>
                    <strong>${result.type === 'error' ? 'Error' : 
                            result.type === 'warning' ? 'Warning' : 
                            'Success'}</strong>
                    <p>${result.message}</p>
                </div>
            </div>
        `).join('');
    }

    async showYamlPreview() {
        try {
            const yaml = await this.apiCall('GET', '/export');
            
            const modal = document.getElementById('yaml-preview-modal');
            const content = document.getElementById('yaml-preview-content');
            
            content.textContent = yaml;
            modal.classList.add('active');

            // Setup preview actions
            document.getElementById('copy-preview-yaml').onclick = () => {
                navigator.clipboard.writeText(yaml).then(() => {
                    this.showToast('success', 'YAML copied to clipboard');
                });
            };

            document.getElementById('download-preview-yaml').onclick = () => {
                this.downloadYaml(yaml);
            };
        } catch (error) {
            this.showToast('error', `Failed to generate preview: ${error.message}`);
        }
    }

    // Utility methods
    updateCounts() {
        const serverCount = this.configs.servers.length;
        const clientGroupCount = this.configs.clientGroups.filter(g => !['direct'].includes(g.id)).length;
        const ruleGroupCount = this.configs.ruleGroups.filter(g => !['allow-all-direct', 'block-all'].includes(g.id)).length;
        const namedPemCount = this.configs.namedPems.length;

        document.getElementById('server-count').textContent = serverCount;
        document.getElementById('client-group-count').textContent = clientGroupCount;
        document.getElementById('rule-group-count').textContent = ruleGroupCount;
        document.getElementById('named-pem-count').textContent = namedPemCount;
    }

    updateRuleSelects() {
        const ruleSelect = document.getElementById('server-rules');
        if (ruleSelect) {
            // Clear existing options except default ones
            const defaultOptions = Array.from(ruleSelect.querySelectorAll('option')).slice(0, 3);
            ruleSelect.innerHTML = '';
            defaultOptions.forEach(option => ruleSelect.appendChild(option));
            
            // Add custom rule groups
            this.configs.ruleGroups.forEach(group => {
                if (!['allow-all-direct', 'block-all'].includes(group.id)) {
                    const option = document.createElement('option');
                    option.value = group.name;
                    option.textContent = group.name;
                    ruleSelect.appendChild(option);
                }
            });
        }
    }

    isValidUUID(uuid) {
        const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
        return uuidRegex.test(uuid);
    }

    closeModals() {
        document.querySelectorAll('.modal').forEach(modal => {
            modal.classList.remove('active');
        });
        this.currentEditingId = null;
        this.currentEditingType = null;
    }

    showToast(type, message) {
        const toast = document.getElementById('toast');
        const icon = toast.querySelector('.toast-icon');
        const messageEl = toast.querySelector('.toast-message');
        
        // Set icon based on type
        const icons = {
            success: 'fas fa-check-circle',
            error: 'fas fa-exclamation-circle',
            warning: 'fas fa-exclamation-triangle',
            info: 'fas fa-info-circle'
        };
        
        icon.className = `toast-icon ${icons[type] || icons.info}`;
        messageEl.textContent = message;
        
        // Set toast type class
        toast.className = `toast ${type}`;
        
        // Show toast
        toast.classList.add('show');
        
        // Auto hide after 5 seconds
        setTimeout(() => {
            toast.classList.remove('show');
        }, 5000);
    }
}

// Initialize the application
const app = new ShoesConfigStudio();

// Make app globally available for onclick handlers
window.app = app;