// api-client.js - API для внешнего клиента управления задачами
const express = require('express');
const router = express.Router();
const path = require('path');
const fs = require('fs');
const axios = require('axios');
const FormData = require('form-data');

module.exports = function(app, db, upload) {
    
    // Middleware для проверки аутентификации
    const requireAuth = (req, res, next) => {
        if (!req.session || !req.session.user) {
            return res.status(401).json({ error: 'Требуется аутентификация' });
        }
        next();
    };

    // Middleware для проверки прав администратора
    const requireAdmin = (req, res, next) => {
        if (!req.session || !req.session.user || req.session.user.role !== 'admin') {
            return res.status(403).json({ error: 'Недостаточно прав' });
        }
        next();
    };

    // ==================== СТРАНИЦА КЛИЕНТА ====================
    
    // GET /client - Страница клиента для работы с API
    app.get('/client', requireAuth, (req, res) => {
        res.sendFile(path.join(__dirname, 'public', 'client.html'));
    });

    // ==================== API ДЛЯ РАБОТЫ С ВНЕШНИМИ СЕРВИСАМИ ====================

    /**
     * POST /api/client/connect - Проверка подключения к внешнему сервису
     */
    router.post('/api/client/connect', requireAuth, async (req, res) => {
        const { api_url, api_key } = req.body;
        const userId = req.session.user.id;

        if (!api_url || !api_key) {
            return res.status(400).json({ 
                error: 'Не указан URL сервиса или API ключ' 
            });
        }

        try {
            // Нормализуем URL
            const baseUrl = api_url.replace(/\/$/, '');
            
            // Пробуем подключиться к сервису
            const response = await axios.get(`${baseUrl}/api/external/tasks`, {
                headers: {
                    'X-API-Key': api_key
                },
                params: {
                    limit: 1
                },
                timeout: 10000
            });

            if (response.data && response.data.success) {
                // Сохраняем подключение в сессии
                if (!req.session.clientConnections) {
                    req.session.clientConnections = {};
                }
                
                const connectionId = Date.now().toString();
                req.session.clientConnections[connectionId] = {
                    id: connectionId,
                    name: `Подключение ${new Date().toLocaleString()}`,
                    url: baseUrl,
                    api_key: api_key,
                    created_at: new Date().toISOString(),
                    last_used: new Date().toISOString()
                };

                // Логируем действие
                const { logActivity } = require('./database');
                if (logActivity) {
                    logActivity(0, userId, 'API_CLIENT_CONNECT', 
                        `Подключение к ${baseUrl} (ID: ${connectionId})`);
                }

                res.json({
                    success: true,
                    message: 'Подключение успешно установлено',
                    connection: req.session.clientConnections[connectionId],
                    server_info: {
                        tasks_count: response.data.meta?.total || 0,
                        user: response.data.meta?.user || 'Unknown'
                    }
                });
            } else {
                res.status(400).json({ 
                    error: 'Неверный ответ от сервера',
                    details: response.data 
                });
            }
        } catch (error) {
            console.error('❌ Ошибка подключения к внешнему сервису:', error.message);
            
            let errorMessage = 'Ошибка подключения к серверу';
            let statusCode = 500;
            
            if (error.code === 'ECONNREFUSED') {
                errorMessage = 'Сервер недоступен (отказ в соединении)';
                statusCode = 503;
            } else if (error.code === 'ETIMEDOUT') {
                errorMessage = 'Превышено время ожидания ответа от сервера';
                statusCode = 504;
            } else if (error.response) {
                if (error.response.status === 401) {
                    errorMessage = 'Неверный API ключ';
                    statusCode = 401;
                } else {
                    errorMessage = `Ошибка сервера: ${error.response.status}`;
                    statusCode = error.response.status;
                }
            }

            res.status(statusCode).json({ 
                error: errorMessage,
                details: error.message 
            });
        }
    });

    /**
     * GET /api/client/connections - Получить список сохраненных подключений
     */
    router.get('/api/client/connections', requireAuth, (req, res) => {
        const connections = req.session.clientConnections || {};
        
        // Маскируем API ключи
        const maskedConnections = Object.values(connections).map(conn => ({
            ...conn,
            api_key: conn.api_key ? 
                conn.api_key.substring(0, 8) + '...' + conn.api_key.substring(conn.api_key.length - 8) : 
                null
        }));

        res.json({
            success: true,
            connections: maskedConnections
        });
    });

    /**
     * GET /api/client/connections/list - Получить список всех подключений для выбора
     */
    router.get('/api/client/connections/list', requireAuth, (req, res) => {
        const connections = req.session.clientConnections || {};
        
        const connectionsList = Object.values(connections).map(conn => ({
            id: conn.id,
            name: conn.name,
            url: conn.url,
            last_used: conn.last_used
        }));

        res.json({
            success: true,
            connections: connectionsList
        });
    });

    /**
     * DELETE /api/client/connections/:id - Удалить сохраненное подключение
     */
    router.delete('/api/client/connections/:id', requireAuth, (req, res) => {
        const { id } = req.params;
        
        if (req.session.clientConnections && req.session.clientConnections[id]) {
            delete req.session.clientConnections[id];
            
            const { logActivity } = require('./database');
            if (logActivity) {
                logActivity(0, req.session.user.id, 'API_CLIENT_DISCONNECT', 
                    `Удалено подключение ${id}`);
            }
            
            res.json({ 
                success: true, 
                message: 'Подключение удалено' 
            });
        } else {
            res.status(404).json({ 
                error: 'Подключение не найдено' 
            });
        }
    });

    /**
     * GET /api/client/tasks - Получить список задач из внешнего сервиса
     */
    router.get('/api/client/tasks', requireAuth, async (req, res) => {
        const { connection_id, api_url, api_key, status, search, limit = 50, offset = 0 } = req.query;
        const userId = req.session.user.id;

        let targetUrl = api_url;
        let targetKey = api_key;

        if (connection_id && req.session.clientConnections && req.session.clientConnections[connection_id]) {
            const connection = req.session.clientConnections[connection_id];
            targetUrl = connection.url;
            targetKey = connection.api_key;
            
            connection.last_used = new Date().toISOString();
        }

        if (!targetUrl || !targetKey) {
            return res.status(400).json({ 
                error: 'Не указан URL сервиса или API ключ' 
            });
        }

        try {
            const baseUrl = targetUrl.replace(/\/$/, '');
            
            const params = { limit, offset };
            if (status) params.status = status;
            
            const response = await axios.get(`${baseUrl}/api/external/tasks`, {
                headers: {
                    'X-API-Key': targetKey
                },
                params: params,
                timeout: 15000
            });

            if (response.data && response.data.success) {
                let tasks = response.data.tasks || [];
                
                if (search && tasks.length > 0) {
                    const searchLower = search.toLowerCase();
                    tasks = tasks.filter(task => 
                        task.title.toLowerCase().includes(searchLower) ||
                        (task.description && task.description.toLowerCase().includes(searchLower))
                    );
                }

                const { logActivity } = require('./database');
                if (logActivity) {
                    logActivity(0, userId, 'API_CLIENT_GET_TASKS', 
                        `Получено ${tasks.length} задач из ${baseUrl}`);
                }

                res.json({
                    success: true,
                    tasks: tasks,
                    meta: {
                        total: tasks.length,
                        limit,
                        offset,
                        source: connection_id ? 'saved_connection' : 'direct',
                        server_info: response.data.meta
                    }
                });
            } else {
                res.status(400).json({ 
                    error: 'Неверный ответ от сервера' 
                });
            }
        } catch (error) {
            console.error('❌ Ошибка получения задач:', error.message);
            
            let errorMessage = 'Ошибка получения задач';
            let statusCode = 500;
            
            if (error.code === 'ECONNREFUSED') {
                errorMessage = 'Сервер недоступен';
                statusCode = 503;
            } else if (error.code === 'ETIMEDOUT') {
                errorMessage = 'Превышено время ожидания';
                statusCode = 504;
            } else if (error.response) {
                if (error.response.status === 401) {
                    errorMessage = 'Неверный API ключ';
                    statusCode = 401;
                } else {
                    errorMessage = `Ошибка сервера: ${error.response.status}`;
                    statusCode = error.response.status;
                }
            }

            res.status(statusCode).json({ 
                error: errorMessage,
                details: error.message 
            });
        }
    });

    /**
     * GET /api/client/tasks/:taskId - Получить детальную информацию о задаче
     */
    router.get('/api/client/tasks/:taskId', requireAuth, async (req, res) => {
        const { taskId } = req.params;
        const { connection_id, api_url, api_key } = req.query;

        let targetUrl = api_url;
        let targetKey = api_key;

        if (connection_id && req.session.clientConnections && req.session.clientConnections[connection_id]) {
            const connection = req.session.clientConnections[connection_id];
            targetUrl = connection.url;
            targetKey = connection.api_key;
        }

        if (!targetUrl || !targetKey) {
            return res.status(400).json({ error: 'Не указан URL сервиса или API ключ' });
        }

        try {
            const baseUrl = targetUrl.replace(/\/$/, '');
            
            const response = await axios.get(`${baseUrl}/api/external/tasks/${taskId}`, {
                headers: {
                    'X-API-Key': targetKey
                },
                timeout: 10000
            });

            if (response.data && response.data.success) {
                res.json({
                    success: true,
                    task: response.data.task
                });
            } else {
                res.status(404).json({ error: 'Задача не найдена' });
            }
        } catch (error) {
            console.error('❌ Ошибка получения задачи:', error.message);
            
            let errorMessage = 'Ошибка получения задачи';
            let statusCode = 500;
            
            if (error.response) {
                if (error.response.status === 404) {
                    errorMessage = 'Задача не найдена';
                    statusCode = 404;
                } else if (error.response.status === 401) {
                    errorMessage = 'Неверный API ключ';
                    statusCode = 401;
                } else {
                    errorMessage = `Ошибка сервера: ${error.response.status}`;
                    statusCode = error.response.status;
                }
            }

            res.status(statusCode).json({ 
                error: errorMessage,
                details: error.message 
            });
        }
    });

    /**
     * PUT /api/client/tasks/:taskId/status - Изменить статус задачи
     */
    router.put('/api/client/tasks/:taskId/status', requireAuth, async (req, res) => {
        const { taskId } = req.params;
        const { connection_id, api_url, api_key } = req.query;
        const { status, comment } = req.body;
        const userId = req.session.user.id;

        if (!status || !['in_progress', 'completed'].includes(status)) {
            return res.status(400).json({ 
                error: 'Статус должен быть "in_progress" или "completed"' 
            });
        }

        let targetUrl = api_url;
        let targetKey = api_key;

        if (connection_id && req.session.clientConnections && req.session.clientConnections[connection_id]) {
            const connection = req.session.clientConnections[connection_id];
            targetUrl = connection.url;
            targetKey = connection.api_key;
        }

        if (!targetUrl || !targetKey) {
            return res.status(400).json({ error: 'Не указан URL сервиса или API ключ' });
        }

        try {
            const baseUrl = targetUrl.replace(/\/$/, '');
            
            const response = await axios.put(
                `${baseUrl}/api/external/tasks/${taskId}/status`,
                { status, comment },
                {
                    headers: {
                        'X-API-Key': targetKey,
                        'Content-Type': 'application/json'
                    },
                    timeout: 10000
                }
            );

            if (response.data && response.data.success) {
                const { logActivity } = require('./database');
                if (logActivity) {
                    logActivity(0, userId, 'API_CLIENT_UPDATE_STATUS', 
                        `Статус задачи ${taskId} изменен на ${status} в ${baseUrl}`);
                }

                res.json({
                    success: true,
                    message: `Статус задачи ${taskId} изменен на "${status}"`,
                    data: response.data
                });
            } else {
                res.status(400).json({ error: 'Не удалось изменить статус' });
            }
        } catch (error) {
            console.error('❌ Ошибка изменения статуса:', error.message);
            
            let errorMessage = 'Ошибка изменения статуса';
            let statusCode = 500;
            
            if (error.response) {
                if (error.response.status === 401) {
                    errorMessage = 'Неверный API ключ';
                    statusCode = 401;
                } else if (error.response.status === 403) {
                    errorMessage = 'Нет прав для изменения статуса';
                    statusCode = 403;
                } else if (error.response.status === 404) {
                    errorMessage = 'Задача не найдена';
                    statusCode = 404;
                } else {
                    errorMessage = error.response.data?.error || `Ошибка сервера: ${error.response.status}`;
                    statusCode = error.response.status;
                }
            }

            res.status(statusCode).json({ 
                error: errorMessage,
                details: error.message 
            });
        }
    });

    /**
     * POST /api/client/tasks/:taskId/files - Загрузить файлы в задачу
     */
    router.post('/api/client/tasks/:taskId/files', requireAuth, upload.array('files', 15), async (req, res) => {
        const { taskId } = req.params;
        const { connection_id, api_url, api_key } = req.query;
        const userId = req.session.user.id;

        if (!req.files || req.files.length === 0) {
            return res.status(400).json({ error: 'Нет файлов для загрузки' });
        }

        let targetUrl = api_url;
        let targetKey = api_key;

        if (connection_id && req.session.clientConnections && req.session.clientConnections[connection_id]) {
            const connection = req.session.clientConnections[connection_id];
            targetUrl = connection.url;
            targetKey = connection.api_key;
        }

        if (!targetUrl || !targetKey) {
            req.files.forEach(file => {
                if (file.path && fs.existsSync(file.path)) {
                    fs.unlinkSync(file.path);
                }
            });
            return res.status(400).json({ error: 'Не указан URL сервиса или API ключ' });
        }

        try {
            const baseUrl = targetUrl.replace(/\/$/, '');
            
            const formData = new FormData();
            
            req.files.forEach(file => {
                formData.append('files', fs.createReadStream(file.path), {
                    filename: file.originalname,
                    contentType: file.mimetype
                });
            });

            const response = await axios.post(
                `${baseUrl}/api/external/tasks/${taskId}/files`,
                formData,
                {
                    headers: {
                        ...formData.getHeaders(),
                        'X-API-Key': targetKey
                    },
                    timeout: 60000,
                    maxContentLength: Infinity,
                    maxBodyLength: Infinity
                }
            );

            req.files.forEach(file => {
                if (file.path && fs.existsSync(file.path)) {
                    fs.unlinkSync(file.path);
                }
            });

            if (response.data && response.data.success) {
                const { logActivity } = require('./database');
                if (logActivity) {
                    logActivity(0, userId, 'API_CLIENT_UPLOAD_FILES', 
                        `Загружено ${req.files.length} файлов в задачу ${taskId} в ${baseUrl}`);
                }

                res.json({
                    success: true,
                    message: `Успешно загружено ${req.files.length} файлов`,
                    data: response.data
                });
            } else {
                res.status(400).json({ error: 'Не удалось загрузить файлы' });
            }
        } catch (error) {
            req.files.forEach(file => {
                if (file.path && fs.existsSync(file.path)) {
                    fs.unlinkSync(file.path);
                }
            });

            console.error('❌ Ошибка загрузки файлов:', error.message);
            
            let errorMessage = 'Ошибка загрузки файлов';
            let statusCode = 500;
            
            if (error.response) {
                if (error.response.status === 401) {
                    errorMessage = 'Неверный API ключ';
                    statusCode = 401;
                } else if (error.response.status === 403) {
                    errorMessage = 'Нет прав для загрузки файлов';
                    statusCode = 403;
                } else if (error.response.status === 404) {
                    errorMessage = 'Задача не найдена';
                    statusCode = 404;
                } else if (error.response.status === 413) {
                    errorMessage = 'Файлы слишком большие';
                    statusCode = 413;
                } else {
                    errorMessage = error.response.data?.error || `Ошибка сервера: ${error.response.status}`;
                    statusCode = error.response.status;
                }
            } else if (error.code === 'ECONNREFUSED') {
                errorMessage = 'Сервер недоступен';
                statusCode = 503;
            } else if (error.code === 'ETIMEDOUT') {
                errorMessage = 'Превышено время ожидания при загрузке';
                statusCode = 504;
            }

            res.status(statusCode).json({ 
                error: errorMessage,
                details: error.message 
            });
        }
    });

    /**
     * GET /api/client/tasks/:taskId/files - Получить список файлов задачи
     */
    router.get('/api/client/tasks/:taskId/files', requireAuth, async (req, res) => {
        const { taskId } = req.params;
        const { connection_id, api_url, api_key } = req.query;

        let targetUrl = api_url;
        let targetKey = api_key;

        if (connection_id && req.session.clientConnections && req.session.clientConnections[connection_id]) {
            const connection = req.session.clientConnections[connection_id];
            targetUrl = connection.url;
            targetKey = connection.api_key;
        }

        if (!targetUrl || !targetKey) {
            return res.status(400).json({ error: 'Не указан URL сервиса или API ключ' });
        }

        try {
            const baseUrl = targetUrl.replace(/\/$/, '');
            
            const response = await axios.get(`${baseUrl}/api/external/tasks/${taskId}`, {
                headers: {
                    'X-API-Key': targetKey
                },
                timeout: 10000
            });

            if (response.data && response.data.success) {
                res.json({
                    success: true,
                    files: response.data.task.files || []
                });
            } else {
                res.status(404).json({ error: 'Задача не найдена' });
            }
        } catch (error) {
            console.error('❌ Ошибка получения файлов:', error.message);
            res.status(500).json({ 
                error: 'Ошибка получения файлов',
                details: error.message 
            });
        }
    });

    /**
     * GET /api/client/tasks/:taskId/files/:fileId/download - Скачать файл
     */
    router.get('/api/client/tasks/:taskId/files/:fileId/download', requireAuth, async (req, res) => {
        const { taskId, fileId } = req.params;
        const { connection_id, api_url, api_key } = req.query;

        let targetUrl = api_url;
        let targetKey = api_key;

        if (connection_id && req.session.clientConnections && req.session.clientConnections[connection_id]) {
            const connection = req.session.clientConnections[connection_id];
            targetUrl = connection.url;
            targetKey = connection.api_key;
        }

        if (!targetUrl || !targetKey) {
            return res.status(400).json({ error: 'Не указан URL сервиса или API ключ' });
        }

        try {
            const baseUrl = targetUrl.replace(/\/$/, '');
            
            const response = await axios({
                method: 'GET',
                url: `${baseUrl}/api/external/tasks/${taskId}/files/${fileId}/download`,
                headers: {
                    'X-API-Key': targetKey
                },
                responseType: 'stream',
                timeout: 30000
            });

            const contentType = response.headers['content-type'] || 'application/octet-stream';
            const contentDisposition = response.headers['content-disposition'] || 'attachment';
            
            res.setHeader('Content-Type', contentType);
            res.setHeader('Content-Disposition', contentDisposition);
            
            response.data.pipe(res);
        } catch (error) {
            console.error('❌ Ошибка скачивания файла:', error.message);
            
            if (error.response) {
                res.status(error.response.status).json({ 
                    error: 'Ошибка при скачивании файла',
                    details: error.response.statusText
                });
            } else {
                res.status(500).json({ 
                    error: 'Ошибка при скачивании файла',
                    details: error.message
                });
            }
        }
    });

    // Подключаем роутер
    app.use(router);
    
    console.log('✅ API клиент для внешних сервисов подключен');
};