/**
 * Transcription editing composable
 * Handles ASR editor, text editor, and segment management
 */

export function useTranscription(state, utils) {
    const {
        showTextEditorModal, showAsrEditorModal, selectedRecording,
        editingTranscriptionContent, editingSegments, availableSpeakers,
        recordings, dropdownPositions, openAsrDropdownIndex
    } = state;

    const { showToast, setGlobalError, nextTick } = utils;

    // =========================================
    // Text Editor Modal
    // =========================================

    const openTranscriptionEditor = () => {
        if (!selectedRecording.value || !selectedRecording.value.transcription) {
            return;
        }

        // Check if transcription is JSON (ASR format)
        try {
            const parsed = JSON.parse(selectedRecording.value.transcription);
            if (Array.isArray(parsed)) {
                openAsrEditorModal();
            } else {
                openTextEditorModal();
            }
        } catch (e) {
            // Not JSON, use text editor
            openTextEditorModal();
        }
    };

    const openTextEditorModal = () => {
        if (!selectedRecording.value) return;
        editingTranscriptionContent.value = selectedRecording.value.transcription || '';
        showTextEditorModal.value = true;
    };

    const closeTextEditorModal = () => {
        showTextEditorModal.value = false;
        editingTranscriptionContent.value = '';
    };

    const saveTranscription = async () => {
        if (!selectedRecording.value) return;
        await saveTranscriptionContent(editingTranscriptionContent.value);
        closeTextEditorModal();
    };

    // =========================================
    // ASR Editor Modal
    // =========================================

    // Helper to pause outer audio player when opening modals with their own player
    const pauseOuterAudioPlayer = () => {
        const outerAudio = document.querySelector('#rightMainColumn audio') || document.querySelector('#rightMainColumn video') ||
                          document.querySelector('.detail-view audio:not(.fixed audio)') || document.querySelector('.detail-view video:not(.fixed video)');
        if (outerAudio && !outerAudio.paused) {
            outerAudio.pause();
        }
    };

    const openAsrEditorModal = async () => {
        if (!selectedRecording.value) return;

        // Pause outer audio player to avoid conflicts with modal's player
        pauseOuterAudioPlayer();

        try {
            const segments = JSON.parse(selectedRecording.value.transcription);

            // Populate available speakers from THIS recording only
            const speakersInTranscript = [...new Set(segments.map(s => s.speaker))].sort();
            availableSpeakers.value = speakersInTranscript;

            editingSegments.value = segments.map((s, i) => ({
                ...s,
                id: i,
                showSuggestions: false,
                filteredSpeakers: [...speakersInTranscript]
            }));

            showAsrEditorModal.value = true;

            // Reset virtual scroll state for fresh modal render
            if (utils.resetAsrEditorScroll) {
                utils.resetAsrEditorScroll();
            }
        } catch (e) {
            console.error("Could not parse transcription as JSON for ASR editor:", e);
            setGlobalError("This transcription is not in the correct format for the ASR editor.");
        }
    };

    const closeAsrEditorModal = () => {
        // Pause any playing modal audio before closing
        const modalAudio = document.querySelector('.fixed.z-50 audio') || document.querySelector('.fixed.z-50 video');
        if (modalAudio) {
            modalAudio.pause();
        }
        // Reset modal audio state (keep main player independent)
        if (utils.resetModalAudioState) {
            utils.resetModalAudioState();
        }

        showAsrEditorModal.value = false;
        editingSegments.value = [];
    };

    const saveAsrTranscription = async () => {
        if (!selectedRecording.value) return;

        // Remove extra UI fields and save the rest
        const contentToSave = JSON.stringify(editingSegments.value.map(({ id, showSuggestions, filteredSpeakers, ...rest }) => rest));

        await saveTranscriptionContent(contentToSave);
        closeAsrEditorModal();
    };

    // =========================================
    // Segment Management
    // =========================================

    const adjustTime = (index, field, amount) => {
        if (editingSegments.value[index]) {
            editingSegments.value[index][field] = Math.max(0,
                editingSegments.value[index][field] + amount
            );
        }
    };

    const filterSpeakerSuggestions = (index) => {
        const segment = editingSegments.value[index];
        if (segment) {
            const query = segment.speaker?.toLowerCase() || '';
            if (query === '') {
                segment.filteredSpeakers = [...availableSpeakers.value];
            } else {
                segment.filteredSpeakers = availableSpeakers.value.filter(
                    speaker => speaker.toLowerCase().includes(query)
                );
            }
        }
    };

    // O(1) dropdown management using single ref instead of O(n) forEach
    const openSpeakerSuggestions = (index) => {
        if (editingSegments.value[index]) {
            // Simply set the open index - O(1) instead of O(n) forEach
            openAsrDropdownIndex.value = index;
            filterSpeakerSuggestions(index);
            updateDropdownPosition(index);
        }
    };

    const closeSpeakerSuggestions = (index) => {
        // Only close if this index is currently open
        if (openAsrDropdownIndex.value === index) {
            openAsrDropdownIndex.value = null;
        }
    };

    const closeAllSpeakerSuggestions = () => {
        // O(1) instead of O(n) - just set to null
        openAsrDropdownIndex.value = null;
    };

    // Helper to check if a dropdown is open (for template v-if)
    const isDropdownOpen = (index) => {
        return openAsrDropdownIndex.value === index;
    };

    const getDropdownPosition = (index) => {
        const pos = dropdownPositions.value[index];
        if (pos) {
            const style = {
                left: pos.left + 'px',
                width: pos.width + 'px'
            };

            // When opening upward, anchor from bottom so dropdown grows upward
            if (pos.openUpward) {
                style.bottom = pos.bottom + 'px';
                style.top = 'auto';
            } else {
                style.top = pos.top + 'px';
                style.bottom = 'auto';
            }

            // Apply calculated max height
            if (pos.maxHeight) {
                style.maxHeight = pos.maxHeight + 'px';
            }
            return style;
        }
        return { top: '0px', left: '0px' };
    };

    const updateDropdownPosition = (index) => {
        nextTick(() => {
            // Find row by data attribute to work correctly with virtual scrolling
            const row = document.querySelector(`.asr-editor-table tbody tr[data-segment-index="${index}"]`);
            if (row) {
                const cell = row.querySelector('td:first-child');
                if (cell) {
                    const rect = cell.getBoundingClientRect();
                    const viewportHeight = window.innerHeight;

                    // Calculate available space above and below
                    const spaceBelow = viewportHeight - rect.bottom - 10;
                    const spaceAbove = rect.top - 10;

                    // Determine max height based on available space (cap at 192px which is max-h-48)
                    const maxDropdownHeight = 192;

                    let top, bottom, openUpward, maxHeight;

                    if (spaceBelow >= maxDropdownHeight || spaceBelow >= spaceAbove) {
                        // Open downward
                        top = rect.bottom + 2;
                        bottom = null;
                        openUpward = false;
                        maxHeight = Math.min(spaceBelow, maxDropdownHeight);
                    } else {
                        // Open upward - anchor from bottom so dropdown grows upward
                        openUpward = true;
                        maxHeight = Math.min(spaceAbove, maxDropdownHeight);
                        // Bottom is distance from viewport bottom to the top of the cell
                        bottom = viewportHeight - rect.top + 2;
                        top = null;
                    }

                    dropdownPositions.value[index] = {
                        top: top,
                        bottom: bottom,
                        left: rect.left,
                        width: rect.width,
                        openUpward: openUpward,
                        maxHeight: maxHeight
                    };
                }
            }
        });
    };

    const selectSpeaker = (index, speaker) => {
        if (editingSegments.value[index]) {
            editingSegments.value[index].speaker = speaker;
            closeSpeakerSuggestions(index);
        }
    };

    const addSegment = () => {
        const lastSegment = editingSegments.value[editingSegments.value.length - 1];
        const newStart = lastSegment ? lastSegment.end_time : 0;

        editingSegments.value.push({
            speaker: availableSpeakers.value[0] || 'Speaker 1',
            start_time: newStart,
            end_time: newStart + 5,
            sentence: '',
            id: editingSegments.value.length,
            showSuggestions: false,
            filteredSpeakers: [...availableSpeakers.value]
        });
    };

    const removeSegment = (index) => {
        editingSegments.value.splice(index, 1);
        // Re-index segments
        editingSegments.value.forEach((seg, i) => {
            seg.id = i;
        });
    };

    const addSegmentBelow = (index) => {
        const currentSegment = editingSegments.value[index];
        const nextSegment = editingSegments.value[index + 1];

        const newStart = currentSegment.end_time;
        const newEnd = nextSegment ? nextSegment.start_time : newStart + 5;

        editingSegments.value.splice(index + 1, 0, {
            speaker: currentSegment.speaker,
            start_time: newStart,
            end_time: newEnd,
            sentence: '',
            id: index + 1,
            showSuggestions: false,
            filteredSpeakers: [...availableSpeakers.value]
        });

        // Re-index segments
        editingSegments.value.forEach((seg, i) => {
            seg.id = i;
        });
    };

    const seekToSegmentTime = (time) => {
        // Find audio elements and use the one in a visible modal (z-50)
        const mediaElements = document.querySelectorAll('.fixed.z-50 audio, .fixed.z-50 video');
        const audioElement = mediaElements.length > 0 ? mediaElements[mediaElements.length - 1] : null;
        if (audioElement) {
            audioElement.currentTime = time;
            audioElement.play();
        }
    };

    const autoResizeTextarea = (event) => {
        const textarea = event.target;
        textarea.style.height = 'auto';
        textarea.style.height = textarea.scrollHeight + 'px';
    };

    // =========================================
    // Save Transcription Content
    // =========================================

    const saveTranscriptionContent = async (content) => {
        if (!selectedRecording.value) return;

        try {
            const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
            const response = await fetch(`/recording/${selectedRecording.value.id}/update_transcription`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-CSRFToken': csrfToken
                },
                body: JSON.stringify({ transcription: content })
            });

            const data = await response.json();
            if (!response.ok) throw new Error(data.error || 'Failed to update transcription');

            // Update recording
            selectedRecording.value.transcription = content;

            const index = recordings.value.findIndex(r => r.id === selectedRecording.value.id);
            if (index !== -1) {
                recordings.value[index].transcription = content;
            }

            showToast('Transcription updated successfully!', 'fa-check-circle');
        } catch (error) {
            setGlobalError(`Failed to save transcription: ${error.message}`);
        }
    };

    // =========================================
    // Save Summary
    // =========================================

    const saveSummary = async (summary) => {
        if (!selectedRecording.value) return;

        try {
            const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
            const payload = {
                id: selectedRecording.value.id,
                title: selectedRecording.value.title,
                participants: selectedRecording.value.participants,
                notes: selectedRecording.value.notes,
                summary: summary,
                meeting_date: selectedRecording.value.meeting_date
            };
            const response = await fetch('/save', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-CSRFToken': csrfToken
                },
                body: JSON.stringify(payload)
            });

            const data = await response.json();
            if (!response.ok) throw new Error(data.error || 'Failed to update summary');

            // Update recording
            selectedRecording.value.summary = summary;

            const index = recordings.value.findIndex(r => r.id === selectedRecording.value.id);
            if (index !== -1) {
                recordings.value[index].summary = summary;
            }

            showToast('Summary saved!', 'fa-check-circle');
        } catch (error) {
            setGlobalError(`Failed to save summary: ${error.message}`);
        }
    };

    // =========================================
    // Save Notes
    // =========================================

    const saveNotes = async (notes) => {
        if (!selectedRecording.value) return;

        // Handle incognito recordings - save to sessionStorage only
        if (selectedRecording.value.incognito) {
            selectedRecording.value.notes = notes;
            // Update sessionStorage
            try {
                const stored = sessionStorage.getItem('speakr_incognito_recording');
                if (stored) {
                    const data = JSON.parse(stored);
                    data.notes = notes;
                    sessionStorage.setItem('speakr_incognito_recording', JSON.stringify(data));
                }
            } catch (e) {
                console.error('[Incognito] Failed to save notes to sessionStorage:', e);
            }
            showToast('Notes saved (in browser only)', 'fa-check-circle');
            return;
        }

        try {
            const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
            const response = await fetch(`/api/recordings/${selectedRecording.value.id}`, {
                method: 'PUT',
                headers: {
                    'Content-Type': 'application/json',
                    'X-CSRFToken': csrfToken
                },
                body: JSON.stringify({ notes })
            });

            const data = await response.json();
            if (!response.ok) throw new Error(data.error || 'Failed to update notes');

            // Update recording
            selectedRecording.value.notes = notes;

            const index = recordings.value.findIndex(r => r.id === selectedRecording.value.id);
            if (index !== -1) {
                recordings.value[index].notes = notes;
            }

            showToast('Notes saved!', 'fa-check-circle');
        } catch (error) {
            setGlobalError(`Failed to save notes: ${error.message}`);
        }
    };

    return {
        // Text editor
        openTranscriptionEditor,
        openTextEditorModal,
        closeTextEditorModal,
        saveTranscription,

        // ASR editor
        openAsrEditorModal,
        closeAsrEditorModal,
        saveAsrTranscription,

        // Segment management
        adjustTime,
        filterSpeakerSuggestions,
        openSpeakerSuggestions,
        closeSpeakerSuggestions,
        closeAllSpeakerSuggestions,
        isDropdownOpen,
        getDropdownPosition,
        updateDropdownPosition,
        selectSpeaker,
        addSegment,
        removeSegment,
        addSegmentBelow,
        seekToSegmentTime,
        autoResizeTextarea,

        // Save
        saveTranscriptionContent,
        saveSummary,
        saveNotes
    };
}
