import fs from 'fs'
import path from 'path'
import { Router } from 'express'
import mongoose from 'mongoose'

import pkg from '../package.json'

import './utils/mongoose'
import { ErrorLog } from './models/ErrorLog'

const folderPath = path.resolve(__dirname, './routers')

const getUrl = (url) => `${process.env.NODE_ENV === 'development' ? '' : '/ms'}${url}`

// Определение типов
interface EndpointStats {
  total: number;
  mock: number;
  real: number;
}

interface FileInfo {
  path: string;
  type: 'file';
  endpoints: EndpointStats;
}

interface DirectoryInfo {
  path: string;
  type: 'directory';
  endpoints: EndpointStats;
  children: (FileInfo | DirectoryInfo)[];
}

interface DirScanResult {
  items: (FileInfo | DirectoryInfo)[];
  totalEndpoints: EndpointStats;
}

// Функция для поиска эндпоинтов в файлах
function countEndpoints(filePath) {
  if (!fs.existsSync(filePath) || !filePath.endsWith('.js') && !filePath.endsWith('.ts')) {
    return { total: 0, mock: 0, real: 0 };
  }
  
  try {
    const content = fs.readFileSync(filePath, 'utf8');
    const httpMethods = ['get', 'post', 'put', 'delete', 'patch'];
    
    const endpointMatches = [];
    let totalCount = 0;
    
    // Собираем все эндпоинты и их контекст
    httpMethods.forEach(method => {
      const regex = new RegExp(`router\\.${method}\\([^{]*{([\\s\\S]*?)(?:}\\s*\\)|},)`, 'gi');
      let match;
      
      while ((match = regex.exec(content)) !== null) {
        totalCount++;
        endpointMatches.push({
          method,
          body: match[1]
        });
      }
    });
    
    // Проверяем каждый эндпоинт - работает с БД или моковый
    let mockCount = 0;
    let realCount = 0;
    
    endpointMatches.forEach(endpoint => {
      const body = endpoint.body;
      
      // Признаки работы с базой данных - модели Mongoose и их методы
      const hasDbInteraction = /\b(find|findOne|findById|create|update|delete|remove|aggregate|count|model)\b.*\(/.test(body) || 
                              /\bmongoose\b/.test(body) || 
                              /\.[a-zA-Z]+Model\b/.test(body);
      
      // Проверка на отправку файлов (считается реальным эндпоинтом)
      const hasFileServing = /res\.sendFile\(/.test(body);
      
      // Проверка на отправку ошибок в JSON (считается реальным эндпоинтом)
      const hasErrorResponse = /res\.json\(\s*{.*?(error|success\s*:\s*false).*?}\)/.test(body) || 
                              /res\.status\(.*?\)\.json\(/.test(body);
      
      // Признаки моковых данных - только явный импорт JSON файлов или отправка JSON без ошибок
      const hasMockJsonImport = /require\s*\(\s*['"`].*\.json['"`]\s*\)/.test(body) || 
                               /import\s+.*\s+from\s+['"`].*\.json['"`]/.test(body);
      
      // JSON ответ, который не является ошибкой (упрощенная проверка)
      const hasJsonResponse = /res\.json\(/.test(body) && !hasErrorResponse;
      
      // Определяем тип эндпоинта
      if (hasDbInteraction || hasFileServing || hasErrorResponse) {
        // Если работает с БД, отправляет файлы или возвращает ошибки - считаем реальным
        realCount++;
      } else if (hasMockJsonImport || hasJsonResponse) {
        // Если импортирует JSON или отправляет JSON без ошибок - считаем моком
        mockCount++;
      } else {
        // По умолчанию считаем реальным
        realCount++;
      }
    });
    
    return {
      total: totalCount,
      mock: mockCount,
      real: realCount
    };
  } catch (err) {
    return { total: 0, mock: 0, real: 0 };
  }
}

// Функция для рекурсивного обхода директорий
function getAllDirs(dir, basePath = ''): DirScanResult {
  const items: (FileInfo | DirectoryInfo)[] = [];
  let totalEndpoints = { total: 0, mock: 0, real: 0 };
  
  try {
    const dirItems = fs.readdirSync(dir);
    
    for (const item of dirItems) {
      const itemPath = path.join(dir, item);
      const relativePath = path.join(basePath, item);
      const stat = fs.statSync(itemPath);
      
      if (stat.isDirectory()) {
        const dirResult = getAllDirs(itemPath, relativePath);
        totalEndpoints.total += dirResult.totalEndpoints.total;
        totalEndpoints.mock += dirResult.totalEndpoints.mock;
        totalEndpoints.real += dirResult.totalEndpoints.real;
        
        items.push({
          path: relativePath,
          type: 'directory',
          endpoints: dirResult.totalEndpoints,
          children: dirResult.items
        });
      } else {
        const fileEndpoints = countEndpoints(itemPath);
        totalEndpoints.total += fileEndpoints.total;
        totalEndpoints.mock += fileEndpoints.mock;
        totalEndpoints.real += fileEndpoints.real;
        
        items.push({
          path: relativePath,
          type: 'file',
          endpoints: fileEndpoints
        });
      }
    }
  } catch (err) {
    console.error(`Ошибка при чтении директории ${dir}:`, err);
  }
  
  return {
    items,
    totalEndpoints
  };
}

// Функция для генерации HTML-списка директорий
function generateDirList(dirs: (FileInfo | DirectoryInfo)[], level = 0) {
  if (dirs.length === 0) return '';
  
  const indent = level * 20;
  
  return `<ul class="directory-list" style="padding-left: ${indent}px">${dirs.map(item => {
    if (item.type === 'directory') {
      const endpointClass = item.endpoints.total > 0 ? 'has-endpoints' : '';
      const endpointInfo = item.endpoints.total > 0 
        ? `<div class="endpoint-stats">
             <span class="endpoint-count total" title="Всего эндпоинтов">${item.endpoints.total}</span>
             <span class="endpoint-count mock" title="Моковые эндпоинты">${item.endpoints.mock}</span>
             <span class="endpoint-count real" title="Реальные эндпоинты">${item.endpoints.real}</span>
           </div>` 
        : '';
      
      return `
        <li class="directory ${endpointClass}">
          <div class="dir-item" data-expandable="true">
            <span class="expand-icon">▶</span>
            <span class="dir-name">${path.basename(item.path)}</span>
            ${endpointInfo}
          </div>
          <div class="subdirectory" style="display: none;">
            ${generateDirList(item.children, level + 1)}
          </div>
        </li>
      `;
    } else {
      const endpointClass = item.endpoints.total > 0 ? 'has-endpoints' : '';
      const endpointInfo = item.endpoints.total > 0 
        ? `<div class="endpoint-stats">
             <span class="endpoint-count total" title="Всего эндпоинтов">${item.endpoints.total}</span>
             <span class="endpoint-count mock" title="Моковые эндпоинты">${item.endpoints.mock}</span>
             <span class="endpoint-count real" title="Реальные эндпоинты">${item.endpoints.real}</span>
           </div>` 
        : '';
      
      return `
        <li class="file ${endpointClass}">
          <div class="file-item" data-path="${item.path}">
            <span class="file-icon">📄</span>
            <span class="file-name">${path.basename(item.path)}</span>
            ${endpointInfo}
          </div>
        </li>
      `;
    }
  }).join('')}</ul>`;
}

const router = Router()

// Эндпоинт для получения содержимого файла
router.get('/file-content', async (req, res) => {
  try {
    const filePath = req.query.path as string;
    if (!filePath) {
      return res.status(400).json({ error: 'Путь к файлу не указан' });
    }
    
    // Используем корень проекта для получения абсолютного пути к файлу
    const projectRoot = path.resolve(__dirname, 'routers');
    const absolutePath = path.join(projectRoot, filePath);
    
    // Проверка, что путь не выходит за пределы проекта
    if (!absolutePath.startsWith(projectRoot)) {
      return res.status(403).json({ error: 'Доступ запрещен' });
    }
    
    if (!fs.existsSync(absolutePath)) {
      return res.status(404).json({ error: 'Файл не найден' });
    }
    
    // Проверяем, что это файл, а не директория
    const stat = fs.statSync(absolutePath);
    if (!stat.isFile()) {
      return res.status(400).json({ error: 'Указанный путь не является файлом' });
    }
    
    // Проверяем размер файла, чтобы не загружать слишком большие файлы
    const MAX_FILE_SIZE = 2 * 1024 * 1024; // 2MB
    if (stat.size > MAX_FILE_SIZE) {
      return res.status(413).json({ 
        error: 'Файл слишком большой',
        size: stat.size,
        maxSize: MAX_FILE_SIZE
      });
    }
    
    const content = fs.readFileSync(absolutePath, 'utf8');
    const fileExtension = path.extname(absolutePath).slice(1);
    
    res.json({ 
      content,
      extension: fileExtension,
      fileName: path.basename(absolutePath)
    });
  } catch (err) {
    console.error('Ошибка при чтении файла:', err);
    res.status(500).json({ error: 'Ошибка при чтении файла' });
  }
});

router.get('/', async (req, res) => {
  // throw new Error('check error message')
  // Используем корень проекта вместо только директории routers
  const projectRoot = path.resolve(__dirname, 'routers');
  const routersPath = path.resolve(__dirname, 'routers');
  const routerFolders = fs.readdirSync(routersPath);
  
  const directoryResult = getAllDirs(projectRoot);
  const totalEndpoints = directoryResult.totalEndpoints.total;
  const mockEndpoints = directoryResult.totalEndpoints.mock;
  const realEndpoints = directoryResult.totalEndpoints.real;
  
  // Получаем последние 10 ошибок
  const latestErrors = await ErrorLog.find().sort({ createdAt: -1 }).limit(10);
  
  // Сформируем HTML для секции с ошибками
  let errorsHtml = '';
  if (latestErrors.length > 0) {
    errorsHtml = latestErrors.map(error => `
      <div class="error-card">
        <div class="error-header">
          <h3 class="error-message">${error.message}</h3>
          <span class="error-date">${new Date(error.createdAt).toLocaleString()}</span>
        </div>
        <div class="error-details">
          ${error.path ? `<div class="error-path">${error.method || 'GET'} ${error.path}</div>` : ''}
          ${error.stack ? `<div class="error-stack">${error.stack}</div>` : ''}
        </div>
      </div>
    `).join('');
  } else {
    errorsHtml = '<p>Нет зарегистрированных ошибок</p>';
  }
  
  // Создаем JavaScript для клиентской части
  const clientScript = `
  document.addEventListener('DOMContentLoaded', function() {
    // Директории
    document.querySelectorAll('.dir-item[data-expandable="true"]').forEach(item => {
      item.addEventListener('click', function(e) {
        const subdirectory = this.nextElementSibling;
        const isExpanded = this.classList.toggle('expanded');
        
        if (isExpanded) {
          subdirectory.style.display = 'block';
          this.querySelector('.expand-icon').textContent = '▼';
        } else {
          subdirectory.style.display = 'none';
          this.querySelector('.expand-icon').textContent = '▶';
        }
        
        e.stopPropagation();
      });
    });
    
    // Модальное окно
    const modal = document.getElementById('fileModal');
    const closeBtn = document.querySelector('.close-modal');
    const fileContent = document.getElementById('fileContent');
    const fileLoader = document.getElementById('fileLoader');
    const modalFileName = document.getElementById('modalFileName');
    
    // Закрытие модального окна
    closeBtn.addEventListener('click', function() {
      modal.style.display = 'none';
    });
    
    window.addEventListener('click', function(event) {
      if (event.target == modal) {
        modal.style.display = 'none';
      }
    });
    
    // Обработчик для файлов
    document.querySelectorAll('.file-item').forEach(item => {
      item.addEventListener('click', async function() {
        const filePath = this.getAttribute('data-path');
        if (!filePath) return;
        
        // Показываем модальное окно и лоадер
        modal.style.display = 'block';
        fileContent.style.display = 'none';
        fileLoader.style.display = 'block';
        modalFileName.textContent = 'Загрузка...';
        
        try {
          const response = await fetch('${getUrl('/file-content?path=')}' + encodeURIComponent(filePath));
          if (!response.ok) {
            throw new Error('Ошибка при загрузке файла');
          }
          
          const data = await response.json();
          
          // Отображаем содержимое файла
          fileLoader.style.display = 'none';
          fileContent.style.display = 'block';
          fileContent.textContent = data.content;
          modalFileName.textContent = data.fileName;
          
          // Подсветка синтаксиса
          const extensionMap = {
            'js': 'javascript',
            'ts': 'typescript',
            'json': 'json',
            'css': 'css',
            'html': 'xml',
            'xml': 'xml',
            'md': 'markdown',
            'yaml': 'yaml',
            'yml': 'yaml',
            'sh': 'bash',
            'bash': 'bash'
          };
          
          const language = extensionMap[data.extension] || '';
          if (language) {
            fileContent.className = 'language-' + language;
            hljs.highlightElement(fileContent);
          }
        } catch (error) {
          fileLoader.style.display = 'none';
          fileContent.style.display = 'block';
          fileContent.textContent = 'Ошибка при загрузке файла: ' + error.message;
          modalFileName.textContent = 'Ошибка';
        }
      });
    });
    
    // Обработчик кнопки очистки ошибок
    const clearErrorsBtn = document.getElementById('clearErrorsBtn');
    const successAction = document.getElementById('successAction');
    
    clearErrorsBtn.addEventListener('click', async function() {
      try {
        const response = await fetch('${getUrl('/clear-old-errors')}', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          }
        });
        
        if (!response.ok) {
          throw new Error('Ошибка при очистке старых ошибок');
        }
        
        const data = await response.json();
        
        // Показываем сообщение об успехе
        successAction.textContent = 'Удалено ' + data.deletedCount + ' записей';
        successAction.style.display = 'block';
        
        // Перезагружаем страницу через 2 секунды
        setTimeout(() => {
          window.location.reload();
        }, 2000);
        
      } catch (error) {
        console.error('Ошибка:', error);
        alert('Произошла ошибка: ' + error.message);
      }
    });
    
    // Обработчик кнопок очистки коллекций
    document.querySelectorAll('.clear-model-btn').forEach(button => {
      button.addEventListener('click', async function() {
        const modelName = this.getAttribute('data-model');
        if (!modelName) return;
        
        if (!confirm(\`Вы уверены, что хотите очистить коллекцию \${modelName}?\`)) {
          return;
        }
        
        try {
          const response = await fetch('' + getUrl('/clear-collection'), {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
            },
            body: JSON.stringify({ modelName })
          });
          
          if (!response.ok) {
            throw new Error('Ошибка при очистке коллекции');
          }
          
          const data = await response.json();
          
          // Показываем сообщение об успехе
          successAction.textContent = 'Коллекция ' + data.model + ' очищена. Удалено ' + data.deletedCount + ' записей';
          successAction.style.display = 'block';
          
          // Перезагружаем страницу через 2 секунды
          setTimeout(() => {
            window.location.reload();
          }, 2000);
          
        } catch (error) {
          console.error('Ошибка:', error);
          alert('Произошла ошибка: ' + error.message);
        }
      });
    });
  });
  `;
  
  res.send(`
    <!DOCTYPE html>
    <html>
    <head>
      <title>Multy Stub v${pkg.version}</title>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/atom-one-dark.min.css">
      <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/languages/javascript.min.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/languages/typescript.min.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/languages/json.min.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/languages/css.min.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/languages/xml.min.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/languages/markdown.min.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/languages/yaml.min.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/languages/bash.min.js"></script>
      <style>
        :root {
          --primary-color: #3f51b5;
          --secondary-color: #f50057;
          --mock-color: #ff9800;
          --real-color: #4caf50;
          --bg-color: #f9f9f9;
          --card-bg: #ffffff;
          --text-color: #333333;
          --border-radius: 8px;
          --shadow: 0 4px 6px rgba(0,0,0,0.1);
          --hover-shadow: 0 6px 12px rgba(0,0,0,0.15);
          --transition: all 0.3s ease;
        }
        
        * {
          box-sizing: border-box;
          margin: 0;
          padding: 0;
        }
        
        body {
          font-family: 'Roboto', Arial, sans-serif;
          line-height: 1.6;
          background-color: var(--bg-color);
          color: var(--text-color);
          padding: 20px;
        }
        
        h1, h2, h3 {
          color: var(--primary-color);
          margin-bottom: 16px;
        }
        
        .container {
          max-width: 1200px;
          margin: 0 auto;
          background-color: var(--card-bg);
          padding: 30px;
          border-radius: var(--border-radius);
          box-shadow: var(--shadow);
        }
        
        .header {
          display: flex;
          justify-content: space-between;
          align-items: center;
          margin-bottom: 30px;
          padding-bottom: 15px;
          border-bottom: 1px solid #eee;
        }
        
        .stats-card {
          background: linear-gradient(135deg, var(--primary-color), #5c6bc0);
          color: white;
          padding: 15px;
          border-radius: var(--border-radius);
          box-shadow: var(--shadow);
          display: flex;
          align-items: center;
          justify-content: center;
          flex-direction: column;
          text-align: center;
        }
        
        .stats-value {
          font-size: 28px;
          font-weight: bold;
        }
        
        .stats-label {
          font-size: 14px;
          opacity: 0.9;
        }
        
        .directory-list {
          list-style-type: none;
          padding-left: 20px;
        }
        
        .directory, .file {
          margin: 5px 0;
          transition: var(--transition);
        }
        
        .dir-item, .file-item {
          padding: 8px 12px;
          border-radius: var(--border-radius);
          cursor: pointer;
          display: flex;
          align-items: center;
          transition: var(--transition);
        }
        
        .dir-item:hover {
          background-color: rgba(63, 81, 181, 0.1);
        }
        
        .file-item:hover {
          background-color: rgba(0, 0, 0, 0.03);
        }
        
        .dir-name {
          font-weight: 500;
          color: var(--primary-color);
        }
        
        .file-name {
          color: var(--text-color);
        }
        
        .expand-icon {
          display: inline-block;
          margin-right: 8px;
          transition: transform 0.3s ease;
          font-size: 12px;
          width: 16px;
          height: 16px;
          text-align: center;
          line-height: 16px;
        }
        
        .file-icon {
          margin-right: 8px;
          font-size: 14px;
        }
        
        .expanded .expand-icon {
          transform: rotate(90deg);
        }
        
        .endpoint-stats {
          display: flex;
          gap: 5px;
          margin-left: 10px;
        }
        
        .endpoint-count {
          font-size: 0.75rem;
          color: #fff;
          padding: 2px 8px;
          border-radius: 12px;
          font-weight: 500;
        }
        
        .endpoint-count.total {
          background-color: var(--secondary-color);
        }
        
        .endpoint-count.mock {
          background-color: var(--mock-color);
        }
        
        .endpoint-count.real {
          background-color: var(--real-color);
        }
        
        .has-endpoints .dir-item {
          border-left: 3px solid var(--secondary-color);
        }
        
        .has-endpoints .file-item {
          border-left: 3px solid var(--secondary-color);
        }
        
        .stats-grid {
          display: grid;
          grid-template-columns: repeat(3, 1fr);
          gap: 15px;
        }
        
        .stats-card.mock {
          background: linear-gradient(135deg, #ff9800, #f57c00);
        }
        
        .stats-card.real {
          background: linear-gradient(135deg, #4caf50, #388e3c);
        }
        
        .section {
          margin-bottom: 30px;
          padding: 20px;
          background-color: var(--card-bg);
          border-radius: var(--border-radius);
          box-shadow: var(--shadow);
          transition: var(--transition);
        }
        
        .section:hover {
          box-shadow: var(--hover-shadow);
        }
        
        .grid {
          display: grid;
          grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
          gap: 20px;
          margin: 20px 0;
        }
        
        .tooltip {
          position: relative;
          display: inline-block;
        }
        
        .tooltip:hover .tooltip-text {
          visibility: visible;
          opacity: 1;
        }
        
        /* Стили для модального окна с содержимым файла */
        .modal {
          display: none;
          position: fixed;
          z-index: 1000;
          left: 0;
          top: 0;
          width: 100%;
          height: 100%;
          background-color: rgba(0,0,0,0.5);
          overflow: auto;
        }
        
        .modal-content {
          background-color: var(--card-bg);
          margin: 5% auto;
          padding: 20px;
          border-radius: var(--border-radius);
          box-shadow: var(--shadow);
          width: 80%;
          max-width: 1000px;
          max-height: 80vh;
          overflow: auto;
        }
        
        .modal-header {
          display: flex;
          justify-content: space-between;
          align-items: center;
          padding-bottom: 10px;
          margin-bottom: 15px;
          border-bottom: 1px solid #eee;
        }
        
        .modal-title {
          margin: 0;
          font-size: 1.5rem;
          color: var(--primary-color);
        }
        
        .close-modal {
          font-size: 28px;
          font-weight: bold;
          cursor: pointer;
          color: #aaa;
          transition: color 0.2s ease;
        }
        
        .close-modal:hover {
          color: var(--secondary-color);
        }
        
        .file-content {
          background-color: #282c34;
          border-radius: var(--border-radius);
          padding: 15px;
          overflow: auto;
          max-height: 60vh;
        }
        
        .file-content pre {
          margin: 0;
          white-space: pre-wrap;
          font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', monospace;
          font-size: 14px;
          line-height: 1.5;
        }
        
        .file-content code {
          display: block;
          width: 100%;
        }
        
        .loader {
          border: 4px solid rgba(0, 0, 0, 0.1);
          border-left: 4px solid var(--primary-color);
          border-radius: 50%;
          width: 30px;
          height: 30px;
          animation: spin 1s linear infinite;
          margin: 30px auto;
        }
        
        @keyframes spin {
          0% { transform: rotate(0deg); }
          100% { transform: rotate(360deg); }
        }
        
        /* Стили для списка моделей */
        .models-grid {
          display: grid;
          grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
          gap: 20px;
          margin-top: 15px;
        }
        
        .model-card {
          background-color: var(--card-bg);
          border-radius: var(--border-radius);
          box-shadow: var(--shadow);
          overflow: hidden;
          transition: var(--transition);
          border-left: 4px solid var(--primary-color);
        }
        
        .model-card:hover {
          box-shadow: var(--hover-shadow);
          transform: translateY(-3px);
        }
        
        .model-header {
          background-color: rgba(63, 81, 181, 0.1);
          padding: 12px 15px;
          display: flex;
          flex-direction: column;
          justify-content: flex-start;
          align-items: flex-start;
          border-bottom: 1px solid #eee;
        }
        
        .model-name {
          margin: 0;
          color: var(--primary-color);
          font-size: 1.2rem;
        }
        
        .model-count {
          background-color: var(--secondary-color);
          color: white;
          padding: 3px 10px;
          border-radius: 12px;
          font-size: 0.8rem;
          font-weight: 500;
        }
        
        .progress-bar-container {
          width: 100%;
          background-color: #f0f0f0;
          border-radius: 10px;
          margin: 10px 0;
          overflow: hidden;
        }
        
        .progress-bar {
          height: 10px;
          background: linear-gradient(90deg, var(--primary-color), #5c6bc0);
          border-radius: 10px;
          transition: width 0.5s ease;
        }
        
        .model-actions {
          display: flex;
          justify-content: flex-end;
          margin-top: 10px;
        }
        
        .model-button {
          background-color: var(--primary-color);
          color: white;
          border: none;
          padding: 5px 10px;
          border-radius: var(--border-radius);
          cursor: pointer;
          font-size: 0.8rem;
          font-weight: 500;
          transition: var(--transition);
        }
        
        .model-button:hover {
          background-color: #303f9f;
          box-shadow: var(--shadow);
        }
        
        .model-button-danger {
          background-color: #f44336;
        }
        
        .model-button-danger:hover {
          background-color: #d32f2f;
        }
        
        .model-details {
          padding: 15px;
        }
        
        .model-fields h4 {
          margin-bottom: 8px;
          font-size: 1rem;
          color: #555;
        }
        
        .fields-list {
          list-style-type: none;
          padding-left: 5px;
        }
        
        .fields-list li {
          margin-bottom: 5px;
          font-size: 0.9rem;
          display: flex;
          align-items: center;
        }
        
        .field-name {
          font-weight: 500;
          margin-right: 5px;
        }
        
        .field-type {
          color: #666;
          background-color: #f0f0f0;
          padding: 2px 6px;
          border-radius: 4px;
          font-size: 0.8rem;
          font-family: monospace;
        }
        
        /* Стили для раздела с ошибками */
        .error-card {
          background-color: var(--card-bg);
          border-radius: var(--border-radius);
          box-shadow: var(--shadow);
          overflow: hidden;
          transition: var(--transition);
          border-left: 4px solid #f44336;
          margin-bottom: 10px;
        }
        
        .error-card:hover {
          box-shadow: var(--hover-shadow);
        }
        
        .error-header {
          background-color: rgba(244, 67, 54, 0.1);
          padding: 12px 15px;
          display: flex;
          justify-content: space-between;
          align-items: center;
          border-bottom: 1px solid #eee;
        }
        
        .error-message {
          margin: 0;
          color: #f44336;
          font-weight: 500;
        }
        
        .error-date {
          color: #777;
          font-size: 0.85rem;
        }
        
        .error-details {
          padding: 15px;
          font-size: 0.9rem;
        }
        
        .error-path {
          margin-bottom: 8px;
          font-family: monospace;
          background-color: #f5f5f5;
          padding: 3px 8px;
          border-radius: 4px;
          display: inline-block;
        }
        
        .error-stack {
          background-color: #282c34;
          color: #e0e0e0;
          padding: 10px;
          border-radius: 4px;
          font-family: monospace;
          white-space: pre-wrap;
          font-size: 0.8rem;
          max-height: 150px;
          overflow-y: auto;
        }
        
        .button {
          background-color: var(--primary-color);
          color: white;
          border: none;
          padding: 10px 15px;
          border-radius: var(--border-radius);
          cursor: pointer;
          font-weight: 500;
          transition: var(--transition);
          text-align: center;
          display: inline-block;
          margin: 10px 0;
        }
        
        .button:hover {
          background-color: #303f9f;
          box-shadow: var(--shadow);
        }
        
        .button-danger {
          background-color: #f44336;
        }
        
        .button-danger:hover {
          background-color: #d32f2f;
        }
        
        .button-success-action {
          display: none;
          background-color: #4CAF50;
          color: white;
          padding: 5px 10px;
          border-radius: 4px;
          position: fixed;
          top: 20px;
          right: 20px;
          z-index: 1000;
          box-shadow: 0 2px 10px rgba(0,0,0,0.2);
          animation: fadeOut 3s forwards;
        }
        
        @keyframes fadeOut {
          0% { opacity: 1; }
          70% { opacity: 1; }
          100% { opacity: 0; }
        }
        
        @media (max-width: 768px) {
          .container {
            padding: 15px;
          }
          
          .grid {
            grid-template-columns: 1fr;
          }
          
          .modal-content {
            width: 95%;
            margin: 10% auto;
          }
        }
      </style>
    </head>
    <body>
      <div class="container">
        <div class="header">
          <h1>Multy Stub v${pkg.version}</h1>
          <div class="stats-grid">
            <div class="stats-card">
              <div class="stats-value">${totalEndpoints}</div>
              <div class="stats-label">Всего эндпоинтов</div>
            </div>
            <div class="stats-card mock">
              <div class="stats-value">${mockEndpoints}</div>
              <div class="stats-label">Моковые эндпоинты</div>
            </div>
            <div class="stats-card real">
              <div class="stats-value">${realEndpoints}</div>
              <div class="stats-label">Реальные эндпоинты</div>
            </div>
          </div>
        </div>
        
        <div class="section">
          <h2>Routers:</h2>
          <div class="grid">
            ${routerFolders.map((f) => `
              <div class="stats-card" style="background: linear-gradient(135deg, #26c6da, #00acc1);">
                <div class="stats-value">${f}</div>
              </div>
            `).join('')}
          </div>
        </div>

        <div class="section">
          <h2>Структура директорий проекта:</h2>
          ${generateDirList(directoryResult.items)}
        </div>

        <div class="section">
          <h2>Models:</h2>
          <div class="models-grid">
            ${
            (await Promise.all(
              (await mongoose.modelNames()).map(async (name) => {
                  const model = mongoose.model(name);
                  const count = await model.countDocuments();
                  // Получаем информацию о полях модели
                  const schema = model.schema;
                  const fields = Object.keys(schema.paths).filter(field => !['__v', '_id'].includes(field));
                  
                  return `
                    <div class="model-card">
                      <div class="model-header">
                        <h3 class="model-name">${name}</h3>
                        <p class="model-count">${count} документов</p>
                      </div>
                      <div class="model-details">
                        <div class="progress-bar-container">
                          <div class="progress-bar" style="width: ${Math.min((count / 1000) * 100, 100)}%"></div>
                        </div>
                        <div class="model-fields">
                          <h4>Поля:</h4>
                          <ul class="fields-list">
                            ${fields.map(field => {
                              const fieldType = schema.paths[field].instance;
                              return `<li><span class="field-name">${field}</span>: <span class="field-type">${fieldType}</span></li>`;
                            }).join('')}
                          </ul>
                        </div>
                        <div class="model-actions">
                          <button class="model-button model-button-danger clear-model-btn" data-model="${name}">Очистить коллекцию</button>
                        </div>
                      </div>
                    </div>
                  `;
                }
              )
            )).join('')
            }
          </div>
        </div>

        <div class="section">
          <h2>Последние ошибки:</h2>
          <button id="clearErrorsBtn" class="button button-danger">Очистить ошибки старше 10 дней</button>
          <div id="errorsContainer">
            ${errorsHtml}
          </div>
        </div>
      </div>
      
      <!-- Модальное окно для отображения содержимого файла -->
      <div id="fileModal" class="modal">
        <div class="modal-content">
          <div class="modal-header">
            <h3 class="modal-title" id="modalFileName">File Name</h3>
            <span class="close-modal">&times;</span>
          </div>
          <div id="fileContentContainer" class="file-content">
            <div id="fileLoader" class="loader"></div>
            <pre><code id="fileContent"></code></pre>
          </div>
        </div>
      </div>

      <div id="successAction" class="button-success-action">Операция выполнена успешно</div>

      <script>${clientScript}</script>
    </body>
    </html>
  `)
})

// Эндпоинт для очистки ошибок старше 10 дней
router.post('/clear-old-errors', async (req, res) => {
  try {
    const tenDaysAgo = new Date();
    tenDaysAgo.setDate(tenDaysAgo.getDate() - 10);
    
    const result = await ErrorLog.deleteMany({ createdAt: { $lt: tenDaysAgo } });
    
    res.json({
      success: true,
      deletedCount: result.deletedCount || 0
    });
  } catch (error) {
    console.error('Ошибка при очистке старых ошибок:', error);
    res.status(500).json({
      success: false,
      error: 'Ошибка при очистке старых ошибок'
    });
  }
});

// Эндпоинт для очистки отдельной коллекции
router.post('/clear-collection', async (req, res) => {
  try {
    const { modelName } = req.body;
    
    if (!modelName) {
      return res.status(400).json({
        success: false,
        error: 'Имя модели не указано'
      });
    }
    
    // Проверяем, существует ли такая модель
    if (!mongoose.modelNames().includes(modelName)) {
      return res.status(404).json({
        success: false,
        error: 'Модель не найдена'
      });
    }
    
    const model = mongoose.model(modelName);
    const result = await model.deleteMany({});
    
    res.json({
      success: true,
      deletedCount: result.deletedCount || 0,
      model: modelName
    });
  } catch (error) {
    console.error(`Ошибка при очистке коллекции:`, error);
    res.status(500).json({
      success: false,
      error: 'Ошибка при очистке коллекции'
    });
  }
});

export default router
