/**
 * Copyright (c) 2024-2026 Тарабанов Александр Викторович
 * All rights reserved.
 * 
 * This software is proprietary and confidential.
 * Unauthorized copying, modification, or distribution is prohibited.
 * 
 * For licensing inquiries: info@hb3-accelerator.com
 * Website: https://hb3-accelerator.com
 * GitHub: https://github.com/VC-HB3-Accelerator
 */

const express = require('express');
const router = express.Router();
const { exec } = require('child_process');
const util = require('util');
const execAsync = util.promisify(exec);
const axios = require('axios');
const logger = require('../utils/logger');
const { requireAuth } = require('../middleware/auth');
const ollamaConfig = require('../services/ollamaConfig');

// Инициализируем один раз
const TIMEOUTS = ollamaConfig.getTimeouts();

// Получение дефолтного base URL для Ollama (для настроек UI)
router.get('/default-base-url', requireAuth, async (req, res) => {
  try {
    const defaultBaseUrl = ollamaConfig.getBaseUrl();
    const fromEnv = !!process.env.OLLAMA_BASE_URL;
    res.json({ 
      baseUrl: defaultBaseUrl,
      fromEnv, // флаг, что URL из переменной окружения
      priority: fromEnv ? 'environment' : 'default'
    });
  } catch (error) {
    logger.error('Error getting default base URL:', error);
    res.status(500).json({ error: 'Failed to get default base URL' });
  }
});

// Проверка статуса подключения к Ollama
router.get('/status', requireAuth, async (req, res) => {
  try {
    const ollamaUrl = ollamaConfig.getBaseUrl();
    
    // Проверяем API Ollama через HTTP запрос
    try {
      const response = await axios.get(`${ollamaUrl}/api/tags`, { 
        timeout: TIMEOUTS.ollamaTags // Централизованный таймаут
      });
      
      const models = response.data.models || [];
      return res.json({ 
        connected: true, 
        message: 'Ollama is running',
        models: models.length,
        availableModels: models.map(m => m.name)
      });
    } catch (apiError) {
      logger.error('Ollama API error:', apiError.message);
      return res.json({ 
        connected: false, 
        error: `Ollama API not responding: ${apiError.message}` 
      });
    }
  } catch (error) {
    logger.error('Error checking Ollama status:', error);
    res.status(500).json({ connected: false, error: 'Failed to check Ollama status' });
  }
});

// Получение списка установленных моделей
router.get('/models', requireAuth, async (req, res) => {
  try {
    const ollamaUrl = ollamaConfig.getBaseUrl();
    
    const response = await axios.get(`${ollamaUrl}/api/tags`, { 
      timeout: TIMEOUTS.ollamaTags 
    });
    
    const models = (response.data.models || []).map(model => ({
      name: model.name,
      id: model.model || model.name,
      size: model.size || 0,
      modified: model.modified_at || 'Unknown'
    }));

    res.json({ models });
  } catch (error) {
    logger.error('Error getting Ollama models:', error);
    res.status(500).json({ error: 'Failed to get models' });
  }
});

// Установка модели
router.post('/install', requireAuth, async (req, res) => {
  const { model } = req.body;
  
  if (!model) {
    return res.status(400).json({ error: 'Model name is required' });
  }

  try {
    logger.info(`Starting installation of model: ${model}`);
    
    // Запускаем установку в фоне
    const installProcess = exec(`docker exec dapp-ollama ollama pull ${model}`, (error, stdout, stderr) => {
      if (error) {
        logger.error(`Error installing model ${model}:`, error);
      } else {
        logger.info(`Successfully installed model: ${model}`);
      }
    });

    // Возвращаем ответ сразу, не ждем завершения
    res.json({ 
      success: true, 
      message: `Installation of ${model} started`,
      processId: installProcess.pid 
    });
  } catch (error) {
    logger.error('Error starting model installation:', error);
    res.status(500).json({ error: 'Failed to start installation' });
  }
});

// Удаление модели
router.delete('/models/:modelName', requireAuth, async (req, res) => {
  const { modelName } = req.params;
  
  if (!modelName) {
    return res.status(400).json({ error: 'Model name is required' });
  }

  try {
    logger.info(`Removing model: ${modelName}`);
    
    const { stdout, stderr } = await execAsync(`docker exec dapp-ollama ollama rm ${modelName}`);
    
    if (stderr && !stderr.includes('deleted')) {
      throw new Error(stderr);
    }
    
    logger.info(`Successfully removed model: ${modelName}`);
    res.json({ success: true, message: `Model ${modelName} removed successfully` });
  } catch (error) {
    logger.error(`Error removing model ${modelName}:`, error);
    res.status(500).json({ error: `Failed to remove model: ${error.message}` });
  }
});

// Получение информации о модели
router.get('/models/:modelName', requireAuth, async (req, res) => {
  const { modelName } = req.params;
  
  try {
    const { stdout } = await execAsync(`docker exec dapp-ollama ollama show ${modelName}`);
    res.json({ model: modelName, info: stdout });
  } catch (error) {
    logger.error(`Error getting model info for ${modelName}:`, error);
    res.status(404).json({ error: 'Model not found' });
  }
});

// Поиск моделей в реестре (если поддерживается)
router.get('/search', requireAuth, async (req, res) => {
  const { query } = req.query;
  
  if (!query) {
    return res.status(400).json({ error: 'Search query is required' });
  }

  try {
    // Пока просто возвращаем популярные модели
    const popularModels = [
      'qwen2.5:7b',
      'llama2:7b',
      'mistral:7b',
      'codellama:7b',
      'llama2:13b',
      'qwen2.5:14b',
      'gemma:7b',
      'phi3:3.8b'
    ];
    
    const filteredModels = popularModels.filter(model => 
      model.toLowerCase().includes(query.toLowerCase())
    );
    
    res.json({ models: filteredModels });
  } catch (error) {
    logger.error('Error searching models:', error);
    res.status(500).json({ error: 'Failed to search models' });
  }
});

module.exports = router; 