/**
 * Reprocessing composable
 * Handles reprocessing transcription and summary
 */

import * as IncognitoStorage from '../db/incognito-storage.js';

export function useReprocess(state, utils) {
    const { nextTick } = Vue;

    const {
        showReprocessModal, showResetModal, reprocessType,
        reprocessRecording, recordingToReset, selectedRecording,
        recordings, asrReprocessOptions, summaryReprocessPromptSource,
        summaryReprocessSelectedTagId, summaryReprocessCustomPrompt,
        availableTags, processingProgress, processingMessage,
        currentlyProcessingFile, uploadQueue
    } = state;

    const { showToast, setGlobalError, onChatComplete } = utils;

    // Store for active polling intervals
    const reprocessingPolls = new Map();

    // =========================================
    // Reprocess Modal
    // =========================================

    const openReprocessModal = (type, recording = null) => {
        reprocessType.value = type;
        reprocessRecording.value = recording || selectedRecording.value;
        showReprocessModal.value = true;

        // Reset options
        if (type === 'transcription') {
            asrReprocessOptions.language = '';
            asrReprocessOptions.min_speakers = '';
            asrReprocessOptions.max_speakers = '';
        } else {
            summaryReprocessPromptSource.value = 'default';
            summaryReprocessSelectedTagId.value = '';
            summaryReprocessCustomPrompt.value = '';
        }
    };

    const closeReprocessModal = () => {
        showReprocessModal.value = false;
        reprocessRecording.value = null;
        reprocessType.value = null;
    };

    const confirmReprocess = openReprocessModal;
    const cancelReprocess = closeReprocessModal;

    // =========================================
    // Reset Status
    // =========================================

    const confirmReset = (recording) => {
        recordingToReset.value = recording;
        showResetModal.value = true;
    };

    const cancelReset = () => {
        showResetModal.value = false;
        recordingToReset.value = null;
    };

    const executeReset = async () => {
        if (!recordingToReset.value) return;

        const recordingId = recordingToReset.value.id;

        // Close the modal first
        cancelReset();

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

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

            // Update recording status in list
            const index = recordings.value.findIndex(r => r.id === recordingId);
            if (index !== -1) {
                recordings.value[index].status = 'FAILED';
            }

            if (selectedRecording.value?.id === recordingId) {
                selectedRecording.value.status = 'FAILED';
            }

            showToast('Recording status reset to FAILED', 'fa-undo');
        } catch (error) {
            setGlobalError(`Failed to reset status: ${error.message}`);
        }
    };

    const executeReprocess = async () => {
        if (!reprocessRecording.value || !reprocessType.value) return;

        const recordingId = reprocessRecording.value.id;
        const type = reprocessType.value;

        closeReprocessModal();

        if (type === 'transcription') {
            await reprocessTranscription(
                recordingId,
                asrReprocessOptions.language,
                asrReprocessOptions.min_speakers,
                asrReprocessOptions.max_speakers
            );
        } else {
            await reprocessSummary(
                recordingId,
                summaryReprocessPromptSource.value,
                summaryReprocessSelectedTagId.value,
                summaryReprocessCustomPrompt.value
            );
        }
    };

    // =========================================
    // Transcription Reprocessing
    // =========================================

    const reprocessTranscription = async (recordingId, language, minSpeakers, maxSpeakers) => {
        if (!recordingId) {
            setGlobalError('No recording ID provided for reprocessing.');
            return;
        }

        try {
            const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
            const requestBody = {
                language: language || ''  // Always send language - empty string means auto-detect
            };
            if (minSpeakers && minSpeakers !== '') requestBody.min_speakers = parseInt(minSpeakers);
            if (maxSpeakers && maxSpeakers !== '') requestBody.max_speakers = parseInt(maxSpeakers);

            const response = await fetch(`/recording/${recordingId}/reprocess_transcription`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-CSRFToken': csrfToken
                },
                body: JSON.stringify(requestBody)
            });

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

            // Update recording status in list
            const index = recordings.value.findIndex(r => r.id === recordingId);
            if (index !== -1) {
                recordings.value[index].status = 'PROCESSING';
            }

            if (selectedRecording.value?.id === recordingId) {
                selectedRecording.value.status = 'PROCESSING';
            }

            showToast('Transcription reprocessing started', 'fa-sync-alt');

            // Start polling for progress
            startReprocessingPoll(recordingId);
        } catch (error) {
            setGlobalError(`Failed to start transcription reprocessing: ${error.message}`);
        }
    };

    // =========================================
    // Summary Reprocessing
    // =========================================

    const reprocessSummary = async (recordingId, promptSource, selectedTagId, customPrompt) => {
        if (!recordingId) {
            setGlobalError('No recording ID provided for reprocessing.');
            return;
        }

        try {
            const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
            const requestBody = { reprocess_summary: true };

            if (promptSource === 'tag' && selectedTagId) {
                const selectedTag = availableTags.value.find(t => t.id == selectedTagId);
                if (selectedTag && selectedTag.custom_prompt) {
                    requestBody.custom_prompt = selectedTag.custom_prompt;
                }
            } else if (promptSource === 'custom' && customPrompt) {
                requestBody.custom_prompt = customPrompt;
            }

            const response = await fetch(`/recording/${recordingId}/reprocess_summary`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-CSRFToken': csrfToken
                },
                body: JSON.stringify(requestBody)
            });

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

            // Update recording status in list
            const index = recordings.value.findIndex(r => r.id === recordingId);
            if (index !== -1) {
                recordings.value[index].status = 'SUMMARIZING';
            }

            if (selectedRecording.value?.id === recordingId) {
                selectedRecording.value.status = 'SUMMARIZING';
            }

            showToast('Summary reprocessing started', 'fa-sync-alt');

            // Start polling for progress
            startReprocessingPoll(recordingId);
        } catch (error) {
            setGlobalError(`Failed to start summary reprocessing: ${error.message}`);
        }
    };

    // =========================================
    // Generate Summary
    // =========================================

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

        try {
            const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');

            // Check if this is an incognito recording
            if (selectedRecording.value.incognito === true) {
                // Use incognito summary endpoint - generate synchronously
                const response = await fetch('/api/recordings/incognito/summary', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                        'X-CSRFToken': csrfToken
                    },
                    body: JSON.stringify({
                        transcription: selectedRecording.value.transcription
                    })
                });

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

                // Update the incognito recording with the new summary
                selectedRecording.value.summary = data.summary;
                selectedRecording.value.summary_html = data.summary_html;

                // Update sessionStorage
                IncognitoStorage.updateIncognitoRecording({
                    summary: data.summary,
                    summary_html: data.summary_html
                });

                showToast('Summary generated', 'fa-file-alt');
                return;
            }

            // Regular recording - use existing flow
            const response = await fetch(`/recording/${selectedRecording.value.id}/generate_summary`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-CSRFToken': csrfToken
                }
            });

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

            selectedRecording.value.status = 'SUMMARIZING';

            const recordingInList = recordings.value.find(r => r.id === selectedRecording.value.id);
            if (recordingInList) {
                recordingInList.status = 'SUMMARIZING';
            }

            showToast('Summary generation started', 'fa-file-alt');

            // Start polling for progress
            startReprocessingPoll(selectedRecording.value.id);
        } catch (error) {
            setGlobalError(`Failed to generate summary: ${error.message}`);
        }
    };

    // =========================================
    // Progress Polling
    // =========================================

    const startReprocessingPoll = (recordingId) => {
        // Stop existing poll if any
        stopReprocessingPoll(recordingId);

        // Track if we've already fetched full data for SUMMARIZING status
        let hasFetchedForSummarizing = false;

        const pollInterval = setInterval(async () => {
            try {
                // Use lightweight status-only endpoint
                const response = await fetch(`/recording/${recordingId}/status`);
                if (!response.ok) throw new Error('Status check failed');

                const statusData = await response.json();

                // Update status in recordings list
                const index = recordings.value.findIndex(r => r.id === recordingId);

                if (index !== -1) {
                    // Create new object to ensure Vue reactivity
                    recordings.value[index] = {
                        ...recordings.value[index],
                        status: statusData.status
                    };
                }

                // Update selectedRecording with new object reference for reactivity
                if (selectedRecording.value?.id === recordingId) {
                    selectedRecording.value = {
                        ...selectedRecording.value,
                        status: statusData.status
                    };
                }

                // Check if summarization has started (fetch transcript) or processing is complete
                if (statusData.status === 'SUMMARIZING' || statusData.status === 'COMPLETED') {
                    // Only fetch once when status first becomes SUMMARIZING
                    const shouldFetch = (statusData.status === 'SUMMARIZING' && !hasFetchedForSummarizing) ||
                                      statusData.status === 'COMPLETED';

                    if (shouldFetch) {
                        // Mark that we've fetched for SUMMARIZING
                        if (statusData.status === 'SUMMARIZING') {
                            hasFetchedForSummarizing = true;
                        }

                        // Only stop polling if COMPLETED, keep polling during SUMMARIZING
                        if (statusData.status === 'COMPLETED') {
                            stopReprocessingPoll(recordingId);
                        }

                        // Fetch the full recording with updated data
                        const fullResponse = await fetch(`/api/recordings/${recordingId}`);

                        if (fullResponse.ok) {
                            const fullData = await fullResponse.json();

                            // Update in recordings list first
                            const currentIndex = recordings.value.findIndex(r => r.id === recordingId);
                            if (currentIndex !== -1) {
                                recordings.value[currentIndex] = fullData;
                            }

                            // Always update selectedRecording if it's the current recording
                            if (selectedRecording.value?.id === recordingId) {
                                selectedRecording.value = fullData;
                                await nextTick();
                            }
                        }

                        if (statusData.status === 'COMPLETED') {
                            showToast('Processing completed!', 'fa-check-circle');
                            // Refresh token budget after LLM operations complete
                            if (onChatComplete) onChatComplete();
                        }
                    }
                } else if (statusData.status === 'FAILED') {
                    stopReprocessingPoll(recordingId);

                    // Fetch full recording data to get error details for display
                    try {
                        const failedResponse = await fetch(`/api/recordings/${recordingId}`);
                        if (failedResponse.ok) {
                            const failedData = await failedResponse.json();

                            // Update in recordings list
                            const currentIndex = recordings.value.findIndex(r => r.id === recordingId);
                            if (currentIndex !== -1) {
                                recordings.value[currentIndex] = failedData;
                            }

                            // Update selectedRecording to show error in transcription panel
                            if (selectedRecording.value?.id === recordingId) {
                                selectedRecording.value = failedData;
                                await nextTick();
                            }
                        }
                    } catch (err) {
                        console.error('Failed to fetch error details:', err);
                    }

                    showToast('Processing failed', 'fa-exclamation-circle');
                }
            } catch (error) {
                console.error('Polling error:', error);
                stopReprocessingPoll(recordingId);
            }
        }, 3000);

        reprocessingPolls.set(recordingId, pollInterval);
    };

    const stopReprocessingPoll = (recordingId) => {
        if (reprocessingPolls.has(recordingId)) {
            clearInterval(reprocessingPolls.get(recordingId));
            reprocessingPolls.delete(recordingId);
        }
    };

    return {
        // Reprocess modal
        openReprocessModal,
        closeReprocessModal,
        confirmReprocess,
        cancelReprocess,
        executeReprocess,

        // Reset status
        confirmReset,
        cancelReset,
        executeReset,

        // Transcription
        reprocessTranscription,

        // Summary
        reprocessSummary,
        generateSummary,

        // Polling
        startReprocessingPoll,
        stopReprocessingPoll
    };
}
