const { app } = require('electron');
const path = require('path');
const { spawn } = require('child_process');

// Helper function to run python commands via the bundled backend
function runPythonCommand(command, kwargs, event) {
    const buildDir = path.resolve(__dirname, '..', '..', 'build');
    let backendPath;
    
    // Determine executable name based on platform
    const executableName = process.platform === 'win32' ? 'fourdst-backend.exe' : 'fourdst-backend';
    
    // Initialize args first
    let args = [command, JSON.stringify(kwargs)];
    
    if (app.isPackaged) {
        // In packaged app, backend is in resources/backend/ directory
        backendPath = path.join(process.resourcesPath, 'backend', executableName);
    } else {
        // In development, use the Python bridge.py directly for faster iteration
        backendPath = 'python';
        // Update args to include the bridge.py path as the first argument
        const bridgePath = path.join(__dirname, '..', 'bridge.py');
        args.unshift(bridgePath);
    }

    console.log(`[MAIN_PROCESS] Spawning backend: ${backendPath}`);
    console.log(`[MAIN_PROCESS] With args: [${args.join(', ')}]`);

    return new Promise((resolve) => {
        const process = spawn(backendPath, args);
        let stdoutBuffer = '';
        let errorOutput = '';

        process.stderr.on('data', (data) => {
            const stderrChunk = data.toString();
            errorOutput += stderrChunk;
            console.error('Backend STDERR:', stderrChunk.trim());
            
            // For fill_bundle, forward stderr to frontend for terminal display
            if (isStreaming && event && command === 'fill_bundle') {
                // Parse stderr lines and send them as progress updates
                const lines = stderrChunk.split('\n').filter(line => line.trim());
                lines.forEach(line => {
                    const trimmedLine = line.trim();
                    
                    // Check if this is a structured progress message
                    if (trimmedLine.startsWith('[PROGRESS] {')) {
                        try {
                            // Extract JSON from [PROGRESS] prefix
                            const jsonStr = trimmedLine.substring('[PROGRESS] '.length);
                            const progressData = JSON.parse(jsonStr);
                            console.log(`[MAIN_PROCESS] Parsed progress data:`, progressData);
                            
                            // Send as proper progress update
                            event.sender.send('fill-bundle-progress', progressData);
                        } catch (e) {
                            console.error(`[MAIN_PROCESS] Failed to parse progress JSON: ${trimmedLine}`, e);
                            // Fallback to stderr if JSON parsing fails
                            event.sender.send('fill-bundle-progress', {
                                type: 'stderr',
                                stderr: trimmedLine
                            });
                        }
                    } else {
                        // Only skip very specific system messages, include everything else as stderr
                        const shouldSkip = trimmedLine.includes('[BRIDGE_INFO]') || 
                                         trimmedLine.includes('--- Python backend bridge') ||
                                         trimmedLine.startsWith('[PROGRESS]') || // Skip non-JSON progress messages
                                         trimmedLine === '';
                        
                        if (!shouldSkip) {
                            console.log(`[MAIN_PROCESS] Forwarding stderr to frontend: ${trimmedLine}`);
                            event.sender.send('fill-bundle-progress', {
                                type: 'stderr',
                                stderr: trimmedLine
                            });
                        }
                    }
                });
            }
        });

        const isStreaming = command === 'fill_bundle';

        process.stdout.on('data', (data) => {
            const chunk = data.toString();
            stdoutBuffer += chunk;

            if (isStreaming && event) {
                // Process buffer line by line for streaming commands
                let newlineIndex;
                while ((newlineIndex = stdoutBuffer.indexOf('\n')) >= 0) {
                    const line = stdoutBuffer.substring(0, newlineIndex).trim();
                    stdoutBuffer = stdoutBuffer.substring(newlineIndex + 1);

                    if (line) {
                        try {
                            const parsed = JSON.parse(line);
                            if (parsed.type === 'progress') {
                                event.sender.send('fill-bundle-progress', parsed.data);
                            } else {
                                // Not a progress update, put it back in the buffer for final processing
                                stdoutBuffer = line + '\n' + stdoutBuffer;
                                break; // Stop processing lines
                            }
                        } catch (e) {
                            // Ignore parsing errors for intermediate lines in a stream
                        }
                    }
                }
            }
        });

        process.on('close', (code) => {
            console.log(`[MAIN_PROCESS] Backend process exited with code ${code}`);
            console.log(`[MAIN_PROCESS] Backend path used: ${backendPath}`);
            console.log(`[MAIN_PROCESS] App packaged: ${app.isPackaged}`);
            console.log(`[MAIN_PROCESS] Resources path: ${process.resourcesPath || 'N/A'}`);
            console.log(`[MAIN_PROCESS] Raw stdout buffer length: ${stdoutBuffer.length}`);
            console.log(`[MAIN_PROCESS] Raw stdout first 200 chars: "${stdoutBuffer.substring(0, 200)}"`);
            console.log(`[MAIN_PROCESS] Error output: "${errorOutput}"`);
            
            let resultData = null;

            try {
                // Core functions now return clean JSON directly
                const finalJson = JSON.parse(stdoutBuffer.trim());
                resultData = finalJson;  // Use the JSON response directly
            } catch (e) {
                console.error(`[MAIN_PROCESS] Could not parse backend output as JSON: ${e}`);
                console.error(`[MAIN_PROCESS] Raw output: "${stdoutBuffer}"`);
                // If parsing fails, return a structured error response
                resultData = { 
                    success: false, 
                    error: `JSON parsing failed: ${e.message}`,
                    raw_output: stdoutBuffer,
                    backend_path: backendPath,
                    is_packaged: app.isPackaged,
                    exit_code: code,
                    stderr_output: errorOutput
                };
            }

            const finalError = errorOutput.trim();
            if (finalError && !resultData) {
                resolve({ success: false, error: finalError });
            } else if (resultData) {
                resolve(resultData);
            } else {
                const errorMessage = finalError || `The script finished without returning a result (exit code: ${code})`;
                resolve({ success: false, error: errorMessage });
            }
        });

        process.on('error', (err) => {
            resolve({ success: false, error: `Failed to start backend process: ${err.message}` });
        });
    });
}

module.exports = {
    runPythonCommand
};
