import { getSpeakers, addSpeaker, deleteSpeaker, generateDialog } from './api.js';
import { API_BASE_URL, API_BASE_URL_FOR_FILES } from './config.js';

// --- Global Inline Notification Helpers --- //
const noticeEl = document.getElementById('global-notice');
const noticeContentEl = document.getElementById('global-notice-content');
const noticeActionsEl = document.getElementById('global-notice-actions');
const noticeCloseBtn = document.getElementById('global-notice-close');

function hideNotice() {
    if (!noticeEl) return;
    noticeEl.style.display = 'none';
    noticeEl.className = 'notice';
    if (noticeContentEl) noticeContentEl.textContent = '';
    if (noticeActionsEl) noticeActionsEl.innerHTML = '';
}

function showNotice(message, type = 'info', options = {}) {
    if (!noticeEl || !noticeContentEl || !noticeActionsEl) {
        console[type === 'error' ? 'error' : 'log']('[NOTICE]', message);
        return () => {};
    }
    const { timeout = null, actions = [] } = options;
    noticeEl.className = `notice notice--${type}`;
    noticeContentEl.textContent = message;
    noticeActionsEl.innerHTML = '';

    actions.forEach(({ text, primary = false, onClick }) => {
        const btn = document.createElement('button');
        btn.textContent = text;
        if (primary) btn.classList.add('btn-primary');
        btn.onclick = () => {
            try { onClick && onClick(); } finally { hideNotice(); }
        };
        noticeActionsEl.appendChild(btn);
    });

    if (noticeCloseBtn) noticeCloseBtn.onclick = hideNotice;
    noticeEl.style.display = 'flex';

    let timerId = null;
    if (timeout && Number.isFinite(timeout)) {
        timerId = window.setTimeout(hideNotice, timeout);
    }
    return () => {
        if (timerId) window.clearTimeout(timerId);
        hideNotice();
    };
}

function confirmAction(message) {
    return new Promise((resolve) => {
        showNotice(message, 'warning', {
            actions: [
                { text: 'Cancel', primary: false, onClick: () => resolve(false) },
                { text: 'Confirm', primary: true, onClick: () => resolve(true) },
            ],
        });
    });
}

document.addEventListener('DOMContentLoaded', async () => {
    console.log('DOM fully loaded and parsed');
    initializeSpeakerManagement();
    await initializeDialogEditor(); // Now properly awaiting the async function
    initializeResultsDisplay(); // Placeholder for now
});

// --- Speaker Management --- //
const speakerListUL = document.getElementById('speaker-list');
const addSpeakerForm = document.getElementById('add-speaker-form');

function initializeSpeakerManagement() {
    loadSpeakers();

    if (addSpeakerForm) {
        addSpeakerForm.addEventListener('submit', async (event) => {
            event.preventDefault();
            const formData = new FormData(addSpeakerForm);
            const speakerName = formData.get('name');
            const audioFile = formData.get('audio_file');

            if (!speakerName || !audioFile || audioFile.size === 0) {
                showNotice('Please provide a speaker name and an audio file.', 'warning', { timeout: 4000 });
                return;
            }

            try {
                const submitBtn = addSpeakerForm.querySelector('button[type="submit"]');
                const prevText = submitBtn ? submitBtn.textContent : null;
                if (submitBtn) { submitBtn.disabled = true; submitBtn.textContent = 'Adding…'; }
                const newSpeaker = await addSpeaker(formData);
                showNotice(`Speaker added: ${newSpeaker.name} (ID: ${newSpeaker.id})`, 'success', { timeout: 3000 });
                addSpeakerForm.reset();
                loadSpeakers(); // Refresh speaker list
            } catch (error) {
                console.error('Failed to add speaker:', error);
                showNotice('Error adding speaker: ' + error.message, 'error');
            } finally {
                const submitBtn = addSpeakerForm.querySelector('button[type="submit"]');
                if (submitBtn) { submitBtn.disabled = false; submitBtn.textContent = 'Add Speaker'; }
            }
        });
    }
}

async function loadSpeakers() {
    if (!speakerListUL) return;
    try {
        const speakers = await getSpeakers();
        speakerListUL.innerHTML = ''; // Clear existing list
        if (speakers.length === 0) {
            const listItem = document.createElement('li');
            listItem.textContent = 'No speakers available.';
            speakerListUL.appendChild(listItem);
            return;
        }
        speakers.forEach(speaker => {
            const listItem = document.createElement('li');
            
            // Create a container for the speaker name and delete button
            const container = document.createElement('div');
            container.style.display = 'flex';
            container.style.justifyContent = 'space-between';
            container.style.alignItems = 'center';
            container.style.width = '100%';
            
            // Add speaker name
            const nameSpan = document.createElement('span');
            nameSpan.textContent = speaker.name;
            container.appendChild(nameSpan);
            
            // Add delete button
            const deleteBtn = document.createElement('button');
            deleteBtn.textContent = 'Delete';
            deleteBtn.classList.add('delete-speaker-btn');
            deleteBtn.onclick = () => handleDeleteSpeaker(speaker.id);
            container.appendChild(deleteBtn);
            
            listItem.appendChild(container);
            speakerListUL.appendChild(listItem);
        });
    } catch (error) {
        console.error('Failed to load speakers:', error);
        speakerListUL.innerHTML = '<li>Error loading speakers. See console for details.</li>';
        showNotice('Error loading speakers: ' + error.message, 'error');
    }
}

async function handleDeleteSpeaker(speakerId) {
    if (!speakerId) {
        showNotice('Cannot delete speaker: Speaker ID is missing.', 'warning', { timeout: 4000 });
        return;
    }
    const ok = await confirmAction(`Are you sure you want to delete speaker ${speakerId}?`);
    if (!ok) return;
    try {
        await deleteSpeaker(speakerId);
        showNotice(`Speaker ${speakerId} deleted successfully.`, 'success', { timeout: 3000 });
        loadSpeakers(); // Refresh speaker list
    } catch (error) {
        console.error(`Failed to delete speaker ${speakerId}:`, error);
        showNotice(`Error deleting speaker: ${error.message}`, 'error');
    }
}

// --- Dialog Editor --- //
let dialogItems = []; // Holds the sequence of speech/silence items
let availableSpeakersCache = []; // To populate speaker dropdown

// Utility: ensure each dialog item has audioUrl, isGenerating, error
function normalizeDialogItem(item) {
    const normalized = {
        ...item,
        audioUrl: item.audioUrl || null,
        isGenerating: item.isGenerating || false,
        error: item.error || null
    };
    
    // Add TTS settings for speech items with defaults
    if (item.type === 'speech') {
        normalized.exaggeration = item.exaggeration ?? 0.5;
        normalized.cfg_weight = item.cfg_weight ?? 0.5;
        normalized.temperature = item.temperature ?? 0.8;
    }
    
    return normalized;
}

async function initializeDialogEditor() {
    const dialogItemsContainer = document.getElementById('dialog-items-container');
    const addSpeechLineBtn = document.getElementById('add-speech-line-btn');
    const addSilenceLineBtn = document.getElementById('add-silence-line-btn');
    const outputBaseNameInput = document.getElementById('output-base-name');
    const generateDialogBtn = document.getElementById('generate-dialog-btn');
    const saveScriptBtn = document.getElementById('save-script-btn');
    const loadScriptBtn = document.getElementById('load-script-btn');
    const loadScriptInput = document.getElementById('load-script-input');

    // Results Display Elements
    const generationLogPre = document.getElementById('generation-log-content'); // Corrected ID
    const audioPlayer = document.getElementById('concatenated-audio-player'); // Corrected ID
    // audioSource will be the audioPlayer itself, no separate element by default in the HTML
    const downloadZipLink = document.getElementById('zip-archive-link'); // Corrected ID
    const zipArchivePlaceholder = document.getElementById('zip-archive-placeholder');
    const resultsDisplaySection = document.getElementById('results-display');

    // Load speakers at startup
    try {
        availableSpeakersCache = await getSpeakers();
        console.log(`Loaded ${availableSpeakersCache.length} speakers for dialog editor`);
    } catch (error) {
        console.error('Error loading speakers at startup:', error);
        // Continue without speakers - they'll be loaded when needed
    }

    // Function to render the current dialogItems array to the DOM as table rows
    function renderDialogItems() {
        if (!dialogItemsContainer) return;
        dialogItemsContainer.innerHTML = '';
        dialogItems = dialogItems.map(normalizeDialogItem); // Ensure all fields present
        dialogItems.forEach((item, index) => {
            const tr = document.createElement('tr');

            // Type column
            const typeTd = document.createElement('td');
            typeTd.classList.add('type-icon-cell');
            if (item.type === 'speech') {
                typeTd.innerHTML = '<span class="dialog-type-icon" title="Speech" aria-label="Speech">🗣️</span>';
            } else {
                typeTd.innerHTML = '<span class="dialog-type-icon" title="Silence" aria-label="Silence">🤫</span>';
            }
            tr.appendChild(typeTd);

            // Speaker column
            const speakerTd = document.createElement('td');
            if (item.type === 'speech') {
                const speakerSelect = document.createElement('select');
                speakerSelect.className = 'dialog-speaker-select';
                availableSpeakersCache.forEach(speaker => {
                    const option = document.createElement('option');
                    option.value = speaker.id;
                    option.textContent = speaker.name;
                    if (speaker.id === item.speaker_id) option.selected = true;
                    speakerSelect.appendChild(option);
                });
                speakerSelect.onchange = (e) => {
                    dialogItems[index].speaker_id = e.target.value;
                };
                speakerTd.appendChild(speakerSelect);
            } else {
                speakerTd.textContent = '—';
            }
            tr.appendChild(speakerTd);

            // Text/Duration column
            const textTd = document.createElement('td');
            textTd.className = 'dialog-editable-cell';
            if (item.type === 'speech') {
                let txt = item.text.length > 60 ? item.text.substring(0, 57) + '…' : item.text;
                textTd.textContent = `"${txt}"`;
                textTd.title = item.text;
            } else {
                textTd.textContent = `${item.duration}s`;
            }
            // Double-click to edit
            textTd.ondblclick = () => {
                textTd.innerHTML = '';
                let input;
                if (item.type === 'speech') {
                    // Use textarea for speech text to enable multi-line editing
                    input = document.createElement('textarea');
                    input.className = 'dialog-edit-textarea';
                    input.value = item.text;
                    input.rows = Math.max(2, Math.ceil(item.text.length / 50)); // Auto-size based on content
                } else {
                    // Use number input for duration
                    input = document.createElement('input');
                    input.className = 'dialog-edit-input';
                    input.type = 'number';
                    input.value = item.duration;
                    input.min = 0.1;
                    input.step = 0.1;
                }
                input.onblur = saveEdit;
                input.onkeydown = (e) => {
                    if (e.key === 'Enter' && item.type === 'silence') {
                        // Only auto-save on Enter for duration inputs
                        input.blur();
                    } else if (e.key === 'Escape') {
                        renderDialogItems();
                    } else if (e.key === 'Enter' && e.ctrlKey && item.type === 'speech') {
                        // Ctrl+Enter to save for speech text
                        input.blur();
                    }
                };
                textTd.appendChild(input);
                input.focus();
                function saveEdit() {
                    if (item.type === 'speech') {
                        dialogItems[index].text = input.value;
                        dialogItems[index].audioUrl = null; // Invalidate audio if text edited
                    } else {
                        let val = parseFloat(input.value);
                        if (!isNaN(val) && val > 0) dialogItems[index].duration = val;
                        dialogItems[index].audioUrl = null;
                    }
                    renderDialogItems();
                }
            };
            tr.appendChild(textTd);

            // Actions column
            const actionsTd = document.createElement('td');
            actionsTd.classList.add('actions');

            // Up button
            const upBtn = document.createElement('button');
            upBtn.innerHTML = '↑';
            upBtn.title = 'Move up';
            upBtn.className = 'move-up-btn';
            upBtn.disabled = index === 0;
            upBtn.onclick = () => {
                if (index > 0) {
                    [dialogItems[index - 1], dialogItems[index]] = [dialogItems[index], dialogItems[index - 1]];
                    renderDialogItems();
                }
            };
            actionsTd.appendChild(upBtn);

            // Down button
            const downBtn = document.createElement('button');
            downBtn.innerHTML = '↓';
            downBtn.title = 'Move down';
            downBtn.className = 'move-down-btn';
            downBtn.disabled = index === dialogItems.length - 1;
            downBtn.onclick = () => {
                if (index < dialogItems.length - 1) {
                    [dialogItems[index], dialogItems[index + 1]] = [dialogItems[index + 1], dialogItems[index]];
                    renderDialogItems();
                }
            };
            actionsTd.appendChild(downBtn);

            // Remove button
            const removeBtn = document.createElement('button');
            removeBtn.innerHTML = '&times;'; // Unicode multiplication sign (X)
            removeBtn.classList.add('remove-dialog-item-btn', 'x-remove-btn');
            removeBtn.setAttribute('aria-label', 'Remove dialog line');
            removeBtn.title = 'Remove';
            removeBtn.onclick = () => {
                dialogItems.splice(index, 1);
                renderDialogItems();
            };
            actionsTd.appendChild(removeBtn);

            // --- NEW: Per-line Generate button ---
            const generateBtn = document.createElement('button');
            generateBtn.innerHTML = '⚡';
            generateBtn.title = 'Generate audio for this line';
            generateBtn.className = 'generate-line-btn';
            generateBtn.disabled = item.isGenerating;
            if (item.isGenerating) generateBtn.classList.add('loading');
            generateBtn.onclick = async () => {
                dialogItems[index].isGenerating = true;
                dialogItems[index].error = null;
                renderDialogItems();
                try {
                    const { generateLine } = await import('./api.js');
                    const payload = { ...item };
                    // Remove fields not needed by backend
                    delete payload.audioUrl; delete payload.isGenerating; delete payload.error;
                    console.log('Sending payload:', payload);
                    const result = await generateLine(payload);
                    console.log('Received result:', result);
                    if (result && result.audio_url) {
                        dialogItems[index].audioUrl = result.audio_url;
                        console.log('Set audioUrl to:', result.audio_url);
                    } else {
                        console.error('Invalid result structure:', result);
                        throw new Error('Invalid response: missing audio_url');
                    }
                } catch (err) {
                    console.error('Error in generateLine:', err);
                    dialogItems[index].error = err.message || 'Failed to generate audio.';
                    showNotice(dialogItems[index].error, 'error');
                } finally {
                    dialogItems[index].isGenerating = false;
                    renderDialogItems();
                }
            };
            actionsTd.appendChild(generateBtn);

            // --- NEW: Per-line Play button ---
            const playBtn = document.createElement('button');
            playBtn.innerHTML = '⏵';
            playBtn.title = item.audioUrl ? 'Play generated audio' : 'No audio generated yet';
            playBtn.className = 'play-line-btn';
            playBtn.disabled = !item.audioUrl;
            playBtn.onclick = () => {
                if (!item.audioUrl) return;
                let audioUrl = item.audioUrl.startsWith('http') ? item.audioUrl : `${API_BASE_URL_FOR_FILES}${item.audioUrl}`;
                // Use a shared audio element or create one per play
                let audio = new window.Audio(audioUrl);
                audio.play();
            };
            actionsTd.appendChild(playBtn);

            // --- NEW: Settings button for speech items ---
            if (item.type === 'speech') {
                const settingsBtn = document.createElement('button');
                settingsBtn.innerHTML = '⚙️';
                settingsBtn.title = 'TTS Settings';
                settingsBtn.className = 'settings-line-btn';
                settingsBtn.onclick = () => {
                    showTTSSettingsModal(item, index);
                };
                actionsTd.appendChild(settingsBtn);
            }

            // Show error if present
            if (item.error) {
                const errorSpan = document.createElement('span');
                errorSpan.className = 'line-error-msg';
                errorSpan.textContent = item.error;
                actionsTd.appendChild(errorSpan);
            }

            tr.appendChild(actionsTd);
            dialogItemsContainer.appendChild(tr);
        });
    }

    const tempInputArea = document.getElementById('temp-input-area');

    function clearTempInputArea() {
        if (tempInputArea) tempInputArea.innerHTML = '';
    }

    if (addSpeechLineBtn) {
        addSpeechLineBtn.addEventListener('click', async () => {
            clearTempInputArea(); // Clear any previous inputs

            if (availableSpeakersCache.length === 0) {
                try {
                    availableSpeakersCache = await getSpeakers();
                } catch (error) {
                    showNotice('Could not load speakers. Please try again.', 'error');
                    console.error('Error fetching speakers for dialog:', error);
                    return;
                }
            }
            if (availableSpeakersCache.length === 0) {
                showNotice('No speakers available. Please add a speaker first.', 'warning', { timeout: 4000 });
                return;
            }

            const speakerSelectLabel = document.createElement('label');
            speakerSelectLabel.textContent = 'Speaker: ';
            speakerSelectLabel.htmlFor = 'temp-speaker-select';
            const speakerSelect = document.createElement('select');
            speakerSelect.id = 'temp-speaker-select';
            availableSpeakersCache.forEach(speaker => {
                const option = document.createElement('option');
                option.value = speaker.id;
                option.textContent = speaker.name;
                speakerSelect.appendChild(option);
            });

            const textInputLabel = document.createElement('label');
            textInputLabel.textContent = ' Text: ';
            textInputLabel.htmlFor = 'temp-speech-text';
            const textInput = document.createElement('textarea');
            textInput.id = 'temp-speech-text';
            textInput.rows = 2;
            textInput.placeholder = 'Enter speech text';

            const addButton = document.createElement('button');
            addButton.textContent = 'Add Speech';
            addButton.onclick = () => {
                const speakerId = speakerSelect.value;
                const text = textInput.value.trim();
                if (!speakerId || !text) {
                    showNotice('Please select a speaker and enter text.', 'warning', { timeout: 4000 });
                    return;
                }
                dialogItems.push(normalizeDialogItem({ type: 'speech', speaker_id: speakerId, text: text }));
                renderDialogItems();
                clearTempInputArea();
            };

            const cancelButton = document.createElement('button');
            cancelButton.textContent = 'Cancel';
            cancelButton.onclick = clearTempInputArea;
            
            if (tempInputArea) {
                tempInputArea.appendChild(speakerSelectLabel);
                tempInputArea.appendChild(speakerSelect);
                tempInputArea.appendChild(textInputLabel);
                tempInputArea.appendChild(textInput);
                tempInputArea.appendChild(addButton);
                tempInputArea.appendChild(cancelButton);
            }
        });
    }

    if (addSilenceLineBtn) {
        addSilenceLineBtn.addEventListener('click', () => {
            clearTempInputArea(); // Clear any previous inputs

            const durationInputLabel = document.createElement('label');
            durationInputLabel.textContent = 'Duration (s): ';
            durationInputLabel.htmlFor = 'temp-silence-duration';
            const durationInput = document.createElement('input');
            durationInput.type = 'number';
            durationInput.id = 'temp-silence-duration';
            durationInput.step = '0.1';
            durationInput.min = '0.1';
            durationInput.placeholder = 'e.g., 0.5';

            const addButton = document.createElement('button');
            addButton.textContent = 'Add Silence';
            addButton.onclick = () => {
                const duration = parseFloat(durationInput.value);
                if (isNaN(duration) || duration <= 0) {
                    showNotice('Invalid duration. Please enter a positive number.', 'warning', { timeout: 4000 });
                    return;
                }
                dialogItems.push(normalizeDialogItem({ type: 'silence', duration: duration }));
                renderDialogItems();
                clearTempInputArea();
            };

            const cancelButton = document.createElement('button');
            cancelButton.textContent = 'Cancel';
            cancelButton.onclick = clearTempInputArea;

            if (tempInputArea) {
                tempInputArea.appendChild(durationInputLabel);
                tempInputArea.appendChild(durationInput);
                tempInputArea.appendChild(addButton);
                tempInputArea.appendChild(cancelButton);
            }
        });
    }

    if (generateDialogBtn && outputBaseNameInput) {
        generateDialogBtn.addEventListener('click', async () => {
            const outputBaseName = outputBaseNameInput.value.trim();
            if (!outputBaseName) {
                showNotice('Please enter an output base name.', 'warning', { timeout: 4000 });
                outputBaseNameInput.focus();
                return;
            }
            if (dialogItems.length === 0) {
                showNotice('Please add at least one speech or silence line to the dialog.', 'warning', { timeout: 4000 });
                return; // Prevent further execution if no dialog items
            }

            const prevText = generateDialogBtn.textContent;
            generateDialogBtn.disabled = true;
            generateDialogBtn.textContent = 'Generating…';
            // Smart dialog-wide generation: use pre-generated audio where present
            const dialogItemsToGenerate = dialogItems.map(item => {
                // Only send minimal fields for items that need generation
                if (item.audioUrl) {
                    return { ...item, use_existing_audio: true, audio_url: item.audioUrl };
                } else {
                    // Remove frontend-only fields
                    const payload = { ...item };
                    delete payload.audioUrl; delete payload.isGenerating; delete payload.error;
                    return payload;
                }
            });

            const payload = {
                output_base_name: outputBaseName,
                dialog_items: dialogItemsToGenerate
            };

            try {
                console.log('Generating dialog with payload:', JSON.stringify(payload, null, 2));
                const result = await generateDialog(payload);
                console.log('Dialog generation successful:', result);

                if (generationLogPre) generationLogPre.textContent = result.log || 'No log output.';
                
                if (result.concatenated_audio_url && audioPlayer) { // Check audioPlayer, not audioSource
                    // Cache-busting: append timestamp to force reload
                    let audioUrl = result.concatenated_audio_url.startsWith('http') ? result.concatenated_audio_url : `${API_BASE_URL_FOR_FILES}${result.concatenated_audio_url}`;
                    audioUrl += (audioUrl.includes('?') ? '&' : '?') + 't=' + Date.now();
                    audioPlayer.src = audioUrl;
                    audioPlayer.load(); // Call load() after setting new source
                    audioPlayer.style.display = 'block';
                } else {
                    if (audioPlayer) audioPlayer.style.display = 'none'; // Ensure it's hidden if no URL
                    if (generationLogPre) generationLogPre.textContent += '\nNo concatenated audio URL found.';
                }

                if (result.zip_archive_url && downloadZipLink) {
                    downloadZipLink.href = result.zip_archive_url.startsWith('http') ? result.zip_archive_url : `${API_BASE_URL_FOR_FILES}${result.zip_archive_url}`;
                    downloadZipLink.textContent = `Download ${outputBaseName}.zip`;
                    downloadZipLink.style.display = 'block';
                    if (zipArchivePlaceholder) zipArchivePlaceholder.style.display = 'none'; // Hide placeholder
                } else {
                    if (downloadZipLink) downloadZipLink.style.display = 'none';
                    if (zipArchivePlaceholder) zipArchivePlaceholder.style.display = 'block'; // Show placeholder if no link
                    if (generationLogPre) generationLogPre.textContent += '\nNo ZIP archive URL found.';
                }

            } catch (error) {
                console.error('Dialog generation failed:', error);
                if (generationLogPre) generationLogPre.textContent = `Error generating dialog: ${error.message}`;
                showNotice(`Error generating dialog: ${error.message}`, 'error');
            }
            finally {
                generateDialogBtn.disabled = false;
                generateDialogBtn.textContent = prevText;
            }
        });
    }

    // --- Save/Load Script Functionality ---
    function saveDialogScript() {
        if (dialogItems.length === 0) {
            showNotice('No dialog items to save. Please add some speech or silence lines first.', 'warning', { timeout: 4000 });
            return;
        }

        // Filter out UI-specific fields and create clean data for export
        const exportData = dialogItems.map(item => {
            const cleanItem = {
                type: item.type
            };
            
            if (item.type === 'speech') {
                cleanItem.speaker_id = item.speaker_id;
                cleanItem.text = item.text;
                // Include TTS parameters if they exist (will use defaults if not present)
                if (item.exaggeration !== undefined) cleanItem.exaggeration = item.exaggeration;
                if (item.cfg_weight !== undefined) cleanItem.cfg_weight = item.cfg_weight;
                if (item.temperature !== undefined) cleanItem.temperature = item.temperature;
            } else if (item.type === 'silence') {
                cleanItem.duration = item.duration;
            }
            
            return cleanItem;
        });

        // Convert to JSONL format (one JSON object per line)
        const jsonlContent = exportData.map(item => JSON.stringify(item)).join('\n');
        
        // Create and download file
        const blob = new Blob([jsonlContent], { type: 'application/jsonl' });
        const url = URL.createObjectURL(blob);
        const link = document.createElement('a');
        
        // Generate filename with timestamp
        const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
        const filename = `dialog_script_${timestamp}.jsonl`;
        
        link.href = url;
        link.download = filename;
        link.style.display = 'none';
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
        URL.revokeObjectURL(url);
        
        console.log(`Dialog script saved as ${filename}`);
        showNotice(`Dialog script saved as ${filename}`, 'success', { timeout: 3000 });
    }

    function loadDialogScript(file) {
        if (!file) {
            showNotice('Please select a file to load.', 'warning', { timeout: 4000 });
            return;
        }

        const reader = new FileReader();
        reader.onload = async function(e) {
            try {
                const content = e.target.result;
                const lines = content.trim().split('\n');
                const loadedItems = [];

                for (let i = 0; i < lines.length; i++) {
                    const line = lines[i].trim();
                    if (!line) continue; // Skip empty lines
                    
                    try {
                        const item = JSON.parse(line);
                        const validatedItem = validateDialogItem(item, i + 1);
                        if (validatedItem) {
                            loadedItems.push(normalizeDialogItem(validatedItem));
                        }
                    } catch (parseError) {
                        console.error(`Error parsing line ${i + 1}:`, parseError);
                        showNotice(`Error parsing line ${i + 1}: ${parseError.message}`, 'error');
                        return;
                    }
                }

                if (loadedItems.length === 0) {
                    showNotice('No valid dialog items found in the file.', 'warning', { timeout: 4000 });
                    return;
                }

                // Confirm replacement if existing items
                if (dialogItems.length > 0) {
                    const confirmed = await confirmAction(
                        `This will replace your current dialog (${dialogItems.length} items) with the loaded script (${loadedItems.length} items). Continue?`
                    );
                    if (!confirmed) return;
                }

                // Ensure speakers are loaded before rendering
                if (availableSpeakersCache.length === 0) {
                    try {
                        availableSpeakersCache = await getSpeakers();
                    } catch (error) {
                        console.error('Error fetching speakers:', error);
                        showNotice('Could not load speakers. Dialog loaded but speaker names may not display correctly.', 'warning', { timeout: 5000 });
                    }
                }

                // Replace current dialog
                dialogItems.splice(0, dialogItems.length, ...loadedItems);
                renderDialogItems();
                
                console.log(`Loaded ${loadedItems.length} dialog items from script`);
                showNotice(`Successfully loaded ${loadedItems.length} dialog items.`, 'success', { timeout: 3000 });
                
            } catch (error) {
                console.error('Error loading dialog script:', error);
                showNotice(`Error loading dialog script: ${error.message}`, 'error');
            }
        };
        
        reader.onerror = function() {
            showNotice('Error reading file. Please try again.', 'error');
        };
        
        reader.readAsText(file);
    }

    function validateDialogItem(item, lineNumber) {
        if (!item || typeof item !== 'object') {
            throw new Error(`Line ${lineNumber}: Invalid item format`);
        }

        if (!item.type || !['speech', 'silence'].includes(item.type)) {
            throw new Error(`Line ${lineNumber}: Invalid or missing type. Must be 'speech' or 'silence'`);
        }

        if (item.type === 'speech') {
            if (!item.speaker_id || typeof item.speaker_id !== 'string') {
                throw new Error(`Line ${lineNumber}: Speech items must have a valid speaker_id`);
            }
            if (!item.text || typeof item.text !== 'string') {
                throw new Error(`Line ${lineNumber}: Speech items must have text`);
            }
            
            // Check if speaker exists in available speakers
            const speakerExists = availableSpeakersCache.some(speaker => speaker.id === item.speaker_id);
            if (availableSpeakersCache.length > 0 && !speakerExists) {
                console.warn(`Line ${lineNumber}: Speaker '${item.speaker_id}' not found in available speakers`);
                // Don't throw error, just warn - speaker might be added later
            }
            
            return {
                type: 'speech',
                speaker_id: item.speaker_id,
                text: item.text
            };
        } else if (item.type === 'silence') {
            if (typeof item.duration !== 'number' || item.duration <= 0) {
                throw new Error(`Line ${lineNumber}: Silence items must have a positive duration number`);
            }
            
            return {
                type: 'silence',
                duration: item.duration
            };
        }
    }

    // Event handlers for save/load
    if (saveScriptBtn) {
        saveScriptBtn.addEventListener('click', saveDialogScript);
    }

    if (loadScriptBtn && loadScriptInput) {
        loadScriptBtn.addEventListener('click', () => {
            loadScriptInput.click();
        });
        
        loadScriptInput.addEventListener('change', (e) => {
            const file = e.target.files[0];
            if (file) {
                loadDialogScript(file);
                // Reset input so same file can be loaded again
                e.target.value = '';
            }
        });
    }

    console.log('Dialog Editor Initialized');
    renderDialogItems(); // Initial render (empty)

    // Add a function to show TTS settings modal
    function showTTSSettingsModal(item, index) {
        const modal = document.getElementById('tts-settings-modal');
        const exaggerationSlider = document.getElementById('tts-exaggeration');
        const exaggerationValue = document.getElementById('tts-exaggeration-value');
        const cfgWeightSlider = document.getElementById('tts-cfg-weight');
        const cfgWeightValue = document.getElementById('tts-cfg-weight-value');
        const temperatureSlider = document.getElementById('tts-temperature');
        const temperatureValue = document.getElementById('tts-temperature-value');
        const saveBtn = document.getElementById('tts-settings-save');
        const cancelBtn = document.getElementById('tts-settings-cancel');
        const closeBtn = document.getElementById('tts-modal-close');

        // Set current values
        exaggerationSlider.value = item.exaggeration || 0.5;
        exaggerationValue.textContent = exaggerationSlider.value;
        cfgWeightSlider.value = item.cfg_weight || 0.5;
        cfgWeightValue.textContent = cfgWeightSlider.value;
        temperatureSlider.value = item.temperature || 0.8;
        temperatureValue.textContent = temperatureSlider.value;

        // Update value displays when sliders change
        const updateValueDisplay = (slider, display) => {
            display.textContent = slider.value;
        };

        exaggerationSlider.oninput = () => updateValueDisplay(exaggerationSlider, exaggerationValue);
        cfgWeightSlider.oninput = () => updateValueDisplay(cfgWeightSlider, cfgWeightValue);
        temperatureSlider.oninput = () => updateValueDisplay(temperatureSlider, temperatureValue);

        // Show modal
        modal.style.display = 'flex';

        // Save settings
        const saveSettings = () => {
            dialogItems[index].exaggeration = parseFloat(exaggerationSlider.value);
            dialogItems[index].cfg_weight = parseFloat(cfgWeightSlider.value);
            dialogItems[index].temperature = parseFloat(temperatureSlider.value);
            
            // Clear any existing audio since settings changed
            dialogItems[index].audioUrl = null;
            
            closeModal();
            renderDialogItems(); // Re-render to reflect changes
            console.log('TTS settings updated for item:', dialogItems[index]);
        };

        // Close modal
        const closeModal = () => {
            modal.style.display = 'none';
            // Clean up event listeners
            exaggerationSlider.oninput = null;
            cfgWeightSlider.oninput = null;
            temperatureSlider.oninput = null;
            saveBtn.onclick = null;
            cancelBtn.onclick = null;
            closeBtn.onclick = null;
            modal.onclick = null;
        };

        // Event listeners
        saveBtn.onclick = saveSettings;
        cancelBtn.onclick = closeModal;
        closeBtn.onclick = closeModal;
        
        // Close modal when clicking outside
        modal.onclick = (e) => {
            if (e.target === modal) {
                closeModal();
            }
        };

        // Close modal on Escape key
        const handleEscape = (e) => {
            if (e.key === 'Escape') {
                closeModal();
                document.removeEventListener('keydown', handleEscape);
            }
        };
        document.addEventListener('keydown', handleEscape);
    }
}

// --- Results Display --- //
function initializeResultsDisplay() {
    const generationLogContent = document.getElementById('generation-log-content');
    const concatenatedAudioPlayer = document.getElementById('concatenated-audio-player');
    const zipArchiveLink = document.getElementById('zip-archive-link');
    const zipArchivePlaceholder = document.getElementById('zip-archive-placeholder');

    // Functions to update these elements will be called by the generateDialog handler
    // e.g., updateLog(message), setAudioSource(url), setZipLink(url)

    console.log('Results Display Initialized');
}
