import {app, BrowserWindow, ipcMain, dialog} from 'electron';
import {exec, spawn} from 'child_process';
import path from 'path';
import {fileURLToPath} from 'url';
import fs from 'fs';
import axios from 'axios';
import ProcessManager from './processManager.js'

const processManager = new ProcessManager(); // 创建进程管理器实例
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);


function createWindow() {
    const win = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
            preload: path.join(__dirname, 'preload.js'), // 确保路径正确
            contextIsolation: true,
            enableRemoteModule: false,
            nodeIntegration: false,
        }
    });

    win.webContents.openDevTools(); // 打开开发者工具进行调试
    win.loadURL('http://localhost:5173'); // 开发环境
    // win.loadURL('http://36.110.106.156:81'); // 生产环境
    console.log('Window created and URL loaded');
}

app.whenReady().then(createWindow);

app.on('window-all-closed', () => {
    if (process.platform !== 'darwin') {
        app.quit();
    }
});


app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) {
        createWindow();
    }
});


// ------------- 进程通信 -------------
ipcMain.handle('dialog:open', async (event, options = {}) => {
    const result = await dialog.showOpenDialog(BrowserWindow.getFocusedWindow() || BrowserWindow.getAllWindows()[0], options);
    return result.canceled ? null : result.filePaths;
});


// 下载文件
ipcMain.handle('download-file', async (event, { url, fileName, savePath, overwriteFlag, dialogFlag, requestType, data }) => {
    try {
        let filePath
        let getPath
        // console.log("url", url)
        // console.log("response", response)
        if (dialogFlag) { // 弹出保存文件对话框
            console.log("savePath", savePath)
            // 获取保存路径
            getPath = await dialog.showSaveDialog({
                defaultPath: path.join(app.getPath('downloads'), fileName)
            })
            filePath = getPath.filePath
            if (getPath.canceled || filePath === "") {
                return { success: false, message: 'File path does not exist' }
            }
        } else {
            filePath = path.join(savePath, fileName);
        }

        console.log("filePath", filePath)

        // 查找文件是否存在
        const fileExists = fs.existsSync(filePath)
        if (fileExists && !overwriteFlag) { // 已存在且不覆盖
            return {success: true, filePath}
        } else { // 不存在
            console.log("url", url)
            let response
            if (requestType === "get") {
                console.log("get...")
                response = await axios.get(url, {responseType: 'stream'});
            } else {
                response = await axios.post(url, data, {responseType: 'stream'});
            }
            console.log("response", response)

            // 写入文件
            const writer = fs.createWriteStream(filePath);

            return new Promise((resolve, reject) => {
                response.data.pipe(writer);

                let error = null;
                writer.on('error', err => {
                    error = err;
                    writer.close();
                    reject(err);
                });

                writer.on('close', () => {
                    if (!error) {
                        resolve({success: true, filePath}); // 返回成功信息
                    } else {
                        reject({success: false, error: error.message}); // 返回错误信息
                    }
                });
            });
        }
    } catch (error) {
        console.error('下载文件出错:', error);
        throw error;
    }
});


// 删除文件
ipcMain.on('delete-file', (event, {fileName, savePath}) => {
    const filePath = path.join(savePath, fileName);
    // 检查文件是否存在
    if (fs.existsSync(filePath)) {
        // 文件存在,尝试删除
        fs.unlink(filePath, (err) => {
            if (err) {
                event.reply('delete-file-response', { success: false, message: err.message });
            } else {
                event.reply('delete-file-response', { success: true, message: 'File deleted successfully' });
            }
        });
    } else {
        // 文件不存在
        event.reply('delete-file-response', { success: false, message: 'File does not exist' });
    }
});

// 上传文件
ipcMain.on('upload-file', async (event, {filePath, uploadUrl}) => {
    if (!fs.existsSync(filePath)) {
        console.log("File does not exist");
        event.reply('upload-file-response', {success: false, message: 'File does not exist'});
        return;
    }
    // 读取文件
    // fs.readFile(filePath, async (err, data) => {
    //     if(err) {
    //         console.log("Error reading file:", err);
    //         event.reply('upload-file-response', { success: false, message: err.message });
    //         return;
    //     }
    //
    //     // 创建formData对象
    //     const formData = new FormData();
    //     formData.append('file', new Blob([data]), path.basename(filePath));
    //
    //     try {
    //         // 使用axios上传文件
    //         const response = await axios.post(uploadUrl, formData, {
    //             headers: {
    //                 'Content-Type': 'multipart/form-data'
    //             }
    //         })
    //         console.log('response', response)
    //         event.reply('upload-file-response', { success: true, message: 'File uploaded successfully' });
    //     } catch (err) {
    //         console.log("Error uploading file:", err);
    //         event.reply('upload-file-response', { success: false, message: err.message });
    //     }
    // })

    try {
        const result = await uploadFile(filePath, uploadUrl);
        console.log("result", result);
        if (result.status) {
            event.reply('upload-file-response', { success: true, message: 'File uploaded successfully', details: result.details });
        } else {
            event.reply('upload-file-response', { success: false, message: 'Error uploading file', details: '' });
        }
    } catch (err) {
        event.reply('upload-file-response', { success: false, message: err.message, details: '' });
    }
});

async function uploadFile(filePath, uploadUrl) {

    const data = fs.readFileSync(filePath)
    // 创建formData对象
    const formData = new FormData();
    formData.append('file', new Blob([data]), path.basename(filePath));

    try {
        // 使用axios上传文件
        const response = await axios.post(uploadUrl, formData, {
            headers: {
                'Content-Type': 'multipart/form-data'
            }
        })
        // console.log('response', response.data)

        return response.data
    } catch (err) {
        console.log("Error uploading file:", err);
        return { status: false, code: '', message: '上传件失败', details: '' };
    }
}

async function uploadFileWithRetry(filePath, uploadUrl, maxRetries = 3) {
    let attempt = 1;

    while (attempt <= maxRetries) {
        console.log("Uploading file - attempt:", attempt);
        try {
            const response = await uploadFile(filePath, uploadUrl);
            console.log("response", response);
            if (response.status) { // 上传成功
                return response;
            } else { // 上传失败
                console.log("Fail to upload file - attempt:", attempt);
                attempt++
            }
        } catch (error) {
            console.log("Error uploading file - attempt:", attempt);
            console.log("Error:", error);
            attempt++
        }
    }
    return { status: false, code: '', message: '上传文件失败', details: '' };
}

// 导入算法镜像
ipcMain.on('docker-import', (event, filePath, tag) => {
    const command = 'bash /home/cicv/work/pji_desktop/docker_import/run_docker_import.sh ' + filePath + ' pji_nav ' + tag
    console.log('Docker import command:', command);
    exec(command, (error, stdout, stderr) => {
        if (error) {
            console.error(`exec error: ${error}`);
            event.reply('docker-import-response', { success: false, message: error.message });
            return;
        } else {
            console.log(`stdout: ${stdout}`);
            console.error(`stderr: ${stderr}`);
            event.reply('docker-import-response', { success: true, message: 'Docker image imported successfully' });
        }
    });
});

// 生成world
ipcMain.on('generate-world', (event, {rosbag_path}) => {
    const command = 'bash /home/cicv/work/pji_desktop/simulation/generate_world.sh ' + rosbag_path
    console.log('World generation command:', command);
    exec(command, (error, stdout, stderr) => {
        if (error) {
            console.error(`exec error: ${error}`);
            event.reply('generate-world-response', { success: false, message: error.message });
        } else {
            console.log(`stdout: ${stdout}`);
            console.error(`stderr: ${stderr}`);
            event.reply('generate-world-response', { success: true, message: 'World generated successfully' });
        }
    });
});

// 启动仿真环境
ipcMain.on('start-container', (event, {zip_file_path, image_name, container_name}) => {

    // 使用 spawn 启动脚本
    const serviceProcess = spawn('bash', ["/home/cicv/work/pji_desktop/simulation/data_preparation.sh", zip_file_path], { detached: true });

    // 设置为后台进程
    serviceProcess.unref();

    // 监听输出
    serviceProcess.stdout.on('data', (data) => {
        console.log(`第一个脚本的输出: ${data}`);
        // 根据第一个脚本的输出判断其是否准备好
        if (data.toString().includes('Data preparation done')) {
            startSecondScript();
        }
    });

    // 监听错误
    serviceProcess.stderr.on('data', (data) => {
        console.error(`执行第一个脚本时出错: ${data}`);
    });

    // 监听关闭
    serviceProcess.on('close', (data) => {
        console.log(`第一个脚本已关闭: ${data}`);
    });

    function startSecondScript() {
        let command = "bash /home/cicv/work/pji_desktop/simulation/start_container.sh " + image_name + " " + container_name
        // 启动第二个脚本
        const script2 = exec(command, (error, stdout, stderr) => {
            if (error) {
                console.error(`执行第二个脚本时出错: ${error}`);
                event.sender.send('start-container-response', { success: false, output: error });
                return;
            }
            console.log(`第二个脚本的输出: ${stdout}`);

            event.sender.send('start-container-response', { success: true, output: stdout });
        });

        script2.on('exit', (code) => {
            console.log(`第二个脚本已退出,退出码: ${code}`);
        });
    }
});

// 执行仿真
ipcMain.on('run-simulation', (event, {random_flag, count, obstacle_flag, default_start_flag, default_end_flag, start_point, end_point}) => {

    const command = 'bash /home/cicv/work/pji_desktop/simulation/run_simulation.sh ' + random_flag + ' ' + count + ' ' + obstacle_flag + ' ' +
        default_start_flag + ' ' + default_end_flag + ' ' + start_point + ' ' + end_point;
    console.log('command:', command);
    // exec(command, (error, stdout, stderr) => {
    //     if (error) {
    //         console.error(`exec error: ${error}`);
    //         event.reply('run-simulation-response', { success: false, message: error.message });
    //     } else {
    //         console.log(`stdout: ${stdout}`);
    //         console.error(`stderr: ${stderr}`);
    //         if (stdout.toString().includes('Evaluation finished')) { // 判断结束标志
    //             event.reply('run-simulation-response', { success: true, message: 'Run simulation successfully' });
    //         } else {
    //             event.reply('run-simulation-response', { success: false, message: 'Error running simulation' });
    //         }
    //     }
    // });

    processManager.startProcess('run-simulation', command, (error, stdout, stderr) => {
        if (error) {
            console.error(`exec error: ${error}`);
            event.reply('run-simulation-response', { success: false, message: error.message });
        } else {
            console.log(`stdout: ${stdout}`);
            console.error(`stderr: ${stderr}`);
            if (stdout.toString().includes('Evaluation finished')) { // 判断结束标志
                event.reply('run-simulation-response', { success: true, message: 'Run simulation successfully' });
            } else {
                event.reply('run-simulation-response', { success: false, message: 'Error running simulation' });
            }
        }
    });

    // 设置超时机制(
    setTimeout(() => {
        processManager.killProcess('run-simulation');
        event.reply('run-simulation-response', { success: false, message: 'Script running timeout' });
    }, 3*60*1000); // 3 分钟
});

// 读取并上传算法评价结果
ipcMain.handle('process-evaluation-files', async (event, {N, equipmentNo, sceneNo}) => {
    const result = []
    const evalDir = "/home/cicv/work/pji_desktop/simulation/data/evaluation";
    const bagDir = "/home/cicv/work/pji_desktop/simulation/data/record_bag";
    console.log('N', N)
    // 记录时间戳
    const timeStamp = Date.now()
    console.log("timeStamp", timeStamp);

    // 遍历评价结果文件夹,读取并上传相关数据
    for (let i = 1; i <= N; i++) {
        const subDir = path.join(evalDir, `${i}/result`);
        console.log("subDir", subDir);
        // 文件路径 - report.json
        const jsonFilePath = path.join(subDir, "report.json");
        console.log("jsonFilePath", jsonFilePath);
        // 文件路径 - report.pdf
        const pdfFilePath = path.join(subDir, "report.pdf");
        console.log("pdfFilePath", pdfFilePath);
        // 文件路径 - test-${i}.bag
        const bagFilePath = path.join(bagDir, `test-${i}.bag`);
        console.log("bagFilePath", bagFilePath);

        const uploadPdfUrl = "http://127.0.0.1:8888/simulation/upload/pdf?equipmentNo=" + equipmentNo + "&sceneNo=" + sceneNo +
            "&timeStamp=" + timeStamp + "&round=" + i;

        const uploadBagUrl = "http://127.0.0.1:8888/simulation/upload/bag?equipmentNo=" + equipmentNo + "&sceneNo=" + sceneNo +
            "&timeStamp=" + timeStamp + "&round=" + i;

        try {
            // 读取json文件
            const jsonData = fs.readFileSync(jsonFilePath, "utf-8");
            const parsedData = JSON.parse(jsonData);
            console.log("parsedData", parsedData);
            // 上传pdf文件
            // 查找pdf文件是否存在
            let pdfFileExists = fs.existsSync(pdfFilePath)
            // pdf文件不存在
            if (!pdfFileExists) break
            // pdf文件存在
            const uploadPdfResult = await uploadFileWithRetry(pdfFilePath, uploadPdfUrl);
            console.log("uploadPdfResult", uploadPdfResult);
            if (!uploadPdfResult.status) {
                break
            }

            // 上传bag文件
            // 查找bag文件是否存在
            let bagFileExists = fs.existsSync(bagFilePath)
            // bag文件不存在
            if (!bagFileExists) break
            // bag文件存在
            const uploadBagResult = await uploadFile(bagFilePath, uploadBagUrl);
            console.log("uploadBagResult", uploadBagResult);
            if (!uploadBagResult.status) { break}
            // 整合结果
            result.push({
                "round": i,
                "jsonData": parsedData,
                "uploadPdfKey": uploadPdfResult.details,
                "uploadBagKey": uploadBagResult.details,
                "timeStamp": timeStamp
            })
        } catch (error) {
            console.log("error", error);
            return { success: false, message: "Error uploading evaluation results", data: [] }
        }
    }
    // 判断数据上传是否完整
    if (result.length === N) {
        return { success: true, message: "Evaluation results uploaded successfully", data: result }
    } else {
        return { success: false, message: "Error uploading evaluation results", data: [] }
    }
})