import { Router } from 'express';
import { authenticateToken } from '../middleware/auth.js';
import logger from '../utils/logger.js';
import { v4 as uuidv4 } from 'uuid';
import axios from 'axios';
import fs from 'fs/promises';
import path from 'path';
import { createWriteStream } from 'fs';
import { pipeline } from 'stream/promises';
import { zipToolsManager } from '../utils/zipToolsManager.js';
const router = Router();
let io;
let configManager;
export function setOnlineDeployDependencies(socketIO, config) {
    io = socketIO;
    configManager = config;
}
export var Platform;
(function (Platform) {
    Platform["WINDOWS"] = "windows";
    Platform["LINUX"] = "linux";
    Platform["MACOS"] = "macos";
})(Platform || (Platform = {}));
const activeDeployments = new Map();
function getCurrentPlatform() {
    const platform = process.platform;
    switch (platform) {
        case 'win32':
            return Platform.WINDOWS;
        case 'linux':
            return Platform.LINUX;
        case 'darwin':
            return Platform.MACOS;
        default:
            return Platform.LINUX;
    }
}
function isGameSupportedOnCurrentPlatform(game) {
    const currentPlatform = getCurrentPlatform();
    return game.supportedPlatforms.includes(currentPlatform);
}
async function validateSponsorKey() {
    try {
        const sponsorConfig = await configManager.getSponsorConfig();
        if (!sponsorConfig || !sponsorConfig.key || !sponsorConfig.isValid) {
            return false;
        }
        if (sponsorConfig.expiryTime && new Date() > new Date(sponsorConfig.expiryTime)) {
            return false;
        }
        return true;
    }
    catch (error) {
        logger.error('验证赞助者密钥失败:', error);
        return false;
    }
}
router.get('/games', authenticateToken, async (req, res) => {
    try {
        const isValidSponsor = await validateSponsorKey();
        if (!isValidSponsor) {
            return res.status(403).json({
                success: false,
                message: '需要有效的赞助者密钥才能访问在线部署功能'
            });
        }
        const currentPlatform = getCurrentPlatform();
        const sponsorConfig = await configManager.getSponsorConfig();
        if (!sponsorConfig || !sponsorConfig.key) {
            return res.status(403).json({
                success: false,
                message: '未找到赞助者密钥'
            });
        }
        const systemName = currentPlatform === Platform.WINDOWS ? 'Windows' :
            currentPlatform === Platform.LINUX ? 'Linux' : 'Linux';
        try {
            const response = await axios.post('http://api.gsm.xiaozhuhouses.asia:10002/api/online-games', {
                system: systemName,
                key: sponsorConfig.key
            }, {
                timeout: 30000,
                headers: {
                    'Content-Type': 'application/json'
                }
            });
            if (response.data.status !== 'success') {
                throw new Error(response.data.message || '获取在线游戏列表失败');
            }
            const gameData = response.data.data || {};
            const supportedGames = Object.entries(gameData).map(([gameName, gameInfo]) => ({
                id: gameName.toLowerCase().replace(/\s+/g, '-'),
                name: gameName,
                description: gameInfo.txt || '',
                image: gameInfo.image || '',
                downloadUrl: gameInfo.download || '',
                type: gameInfo.type || [],
                supportedPlatforms: [currentPlatform],
                supported: true,
                currentPlatform
            }));
            logger.info(`成功获取到 ${supportedGames.length} 个在线游戏`);
            res.json({
                success: true,
                data: supportedGames
            });
        }
        catch (apiError) {
            logger.error('请求第三方API失败:', apiError.message);
            res.json({
                success: true,
                data: [],
                message: '暂时无法获取在线游戏列表，请稍后重试'
            });
        }
    }
    catch (error) {
        logger.error('获取在线游戏列表失败:', error);
        res.status(500).json({
            success: false,
            message: '获取在线游戏列表失败'
        });
    }
});
router.post('/deploy', authenticateToken, async (req, res) => {
    try {
        const isValidSponsor = await validateSponsorKey();
        if (!isValidSponsor) {
            return res.status(403).json({
                success: false,
                message: '需要有效的赞助者密钥才能使用在线部署功能'
            });
        }
        const { gameId, installPath, socketId } = req.body;
        if (!gameId || !installPath) {
            return res.status(400).json({
                success: false,
                message: '缺少必要参数'
            });
        }
        const deploymentId = uuidv4();
        const deploymentProcess = {
            id: deploymentId,
            gameId,
            installPath,
            status: 'running',
            startTime: new Date()
        };
        activeDeployments.set(deploymentId, deploymentProcess);
        setImmediate(async () => {
            try {
                if (deploymentProcess.status === 'cancelled') {
                    return;
                }
                if (io && socketId) {
                    io.to(socketId).emit('online-deploy-log', {
                        deploymentId,
                        message: `开始部署 ${gameId}...`,
                        type: 'info',
                        timestamp: new Date().toISOString()
                    });
                }
                if (io && socketId) {
                    io.to(socketId).emit('online-deploy-log', {
                        deploymentId,
                        message: '正在验证安装路径...',
                        type: 'info',
                        timestamp: new Date().toISOString()
                    });
                    io.to(socketId).emit('online-deploy-progress', {
                        deploymentId,
                        percentage: 10,
                        currentStep: '验证安装路径'
                    });
                }
                await fs.mkdir(installPath, { recursive: true });
                if (deploymentProcess.status === 'cancelled')
                    return;
                if (io && socketId) {
                    io.to(socketId).emit('online-deploy-log', {
                        deploymentId,
                        message: '正在获取游戏下载信息...',
                        type: 'info',
                        timestamp: new Date().toISOString()
                    });
                    io.to(socketId).emit('online-deploy-progress', {
                        deploymentId,
                        percentage: 20,
                        currentStep: '获取下载信息'
                    });
                }
                const sponsorConfig = await configManager.getSponsorConfig();
                const currentPlatform = getCurrentPlatform();
                const systemName = currentPlatform === Platform.WINDOWS ? 'Windows' : 'Linux';
                const gameListResponse = await axios.post('http://api.gsm.xiaozhuhouses.asia:10002/api/online-games', {
                    system: systemName,
                    key: sponsorConfig.key
                });
                if (gameListResponse.data.status !== 'success') {
                    throw new Error('无法获取游戏下载信息');
                }
                const gameData = gameListResponse.data.data || {};
                const gameEntry = Object.entries(gameData).find(([name]) => name.toLowerCase().replace(/\s+/g, '-') === gameId);
                if (!gameEntry || !gameEntry[1].download) {
                    throw new Error('未找到游戏下载链接');
                }
                const downloadUrl = gameEntry[1].download;
                const gameName = gameEntry[0];
                if (deploymentProcess.status === 'cancelled')
                    return;
                if (io && socketId) {
                    io.to(socketId).emit('online-deploy-log', {
                        deploymentId,
                        message: `正在下载 ${gameName}...`,
                        type: 'info',
                        timestamp: new Date().toISOString()
                    });
                }
                const fileName = path.basename(downloadUrl) || `${gameId}.zip`;
                const downloadPath = path.join(installPath, fileName);
                const response = await axios({
                    method: 'GET',
                    url: downloadUrl,
                    responseType: 'stream',
                    timeout: 300000
                });
                const totalSize = parseInt(String(response.headers['content-length'] || '0'), 10);
                let downloadedSize = 0;
                const writer = createWriteStream(downloadPath);
                response.data.on('data', (chunk) => {
                    if (deploymentProcess.status === 'cancelled') {
                        response.data.destroy();
                        writer.destroy();
                        return;
                    }
                    downloadedSize += chunk.length;
                    const percentage = totalSize > 0 ? Math.round((downloadedSize / totalSize) * 50) + 20 : 30;
                    if (io && socketId) {
                        io.to(socketId).emit('online-deploy-progress', {
                            deploymentId,
                            percentage,
                            currentStep: `下载中... ${Math.round(downloadedSize / 1024 / 1024)}MB${totalSize > 0 ? `/${Math.round(totalSize / 1024 / 1024)}MB` : ''}`
                        });
                    }
                });
                await pipeline(response.data, writer);
                if (deploymentProcess.status === 'cancelled') {
                    try {
                        await fs.unlink(downloadPath);
                    }
                    catch { }
                    return;
                }
                if (io && socketId) {
                    io.to(socketId).emit('online-deploy-log', {
                        deploymentId,
                        message: '正在解压游戏文件...',
                        type: 'info',
                        timestamp: new Date().toISOString()
                    });
                    io.to(socketId).emit('online-deploy-progress', {
                        deploymentId,
                        percentage: 80,
                        currentStep: '解压文件'
                    });
                }
                const ext = path.extname(downloadPath).toLowerCase();
                if (ext === '.7z') {
                    await zipToolsManager.extract7z(downloadPath, installPath);
                }
                else {
                    await zipToolsManager.extractZip(downloadPath, installPath);
                }
                await fs.unlink(downloadPath);
                if (deploymentProcess.status === 'cancelled')
                    return;
                if (io && socketId) {
                    io.to(socketId).emit('online-deploy-log', {
                        deploymentId,
                        message: '部署完成！',
                        type: 'success',
                        timestamp: new Date().toISOString()
                    });
                    io.to(socketId).emit('online-deploy-progress', {
                        deploymentId,
                        percentage: 100,
                        currentStep: '部署完成'
                    });
                }
                deploymentProcess.status = 'completed';
                if (io && socketId) {
                    io.to(socketId).emit('online-deploy-complete', {
                        deploymentId,
                        success: true,
                        result: {
                            installPath: installPath,
                            gameId,
                            gameName,
                            message: `${gameName} 部署成功！`
                        }
                    });
                }
            }
            catch (error) {
                logger.error('在线游戏部署失败:', error);
                deploymentProcess.status = 'failed';
                if (io && socketId) {
                    io.to(socketId).emit('online-deploy-complete', {
                        deploymentId,
                        success: false,
                        error: error instanceof Error ? error.message : '部署失败'
                    });
                }
            }
            finally {
                setTimeout(() => {
                    activeDeployments.delete(deploymentId);
                }, 300000);
            }
        });
        res.json({
            success: true,
            data: {
                deploymentId
            },
            message: '部署已开始'
        });
    }
    catch (error) {
        logger.error('启动在线游戏部署失败:', error);
        res.status(500).json({
            success: false,
            message: '启动部署失败'
        });
    }
});
router.post('/cancel/:deploymentId', authenticateToken, async (req, res) => {
    try {
        const { deploymentId } = req.params;
        const deployment = activeDeployments.get(deploymentId);
        if (!deployment) {
            return res.status(404).json({
                success: false,
                message: '部署任务不存在'
            });
        }
        deployment.status = 'cancelled';
        if (io) {
            io.emit('online-deploy-log', {
                deploymentId,
                message: '部署已被用户取消',
                type: 'warning',
                timestamp: new Date().toISOString()
            });
            io.emit('online-deploy-complete', {
                deploymentId,
                success: false,
                error: '部署已取消'
            });
        }
        setTimeout(() => {
            activeDeployments.delete(deploymentId);
        }, 5000);
        res.json({
            success: true,
            message: '部署已取消'
        });
    }
    catch (error) {
        logger.error('取消在线游戏部署失败:', error);
        res.status(500).json({
            success: false,
            message: '取消部署失败'
        });
    }
});
router.get('/deployments', authenticateToken, async (req, res) => {
    try {
        const deployments = Array.from(activeDeployments.values());
        res.json({
            success: true,
            data: deployments
        });
    }
    catch (error) {
        logger.error('获取活动部署列表失败:', error);
        res.status(500).json({
            success: false,
            message: '获取部署列表失败'
        });
    }
});
export default router;
