const User = require('../models/User');
const Conversation = require('../models/Conversation');
const Message = require('../models/Message');
const ProfileView = require('../models/ProfileView');

/**
 * @desc    Получить список всех пользователей
 * @route   GET /api/admin/users
 * @access  Admin
 */
const getAllUsers = async (req, res) => {
  try {
    const { search, page = 1, limit = 20, isActive } = req.query;
    const skip = (page - 1) * limit;

    // Создание фильтра
    const filter = {};
    
    // Добавляем поиск по имени или email, если указан
    if (search) {
      filter.$or = [
        { name: { $regex: search, $options: 'i' } },
        { email: { $regex: search, $options: 'i' } }
      ];
    }

    // Фильтр по статусу активности, если указан
    if (isActive !== undefined) {
      filter.isActive = isActive === 'true';
    }

    // Исключаем админа из результатов выдачи
    filter.isAdmin = { $ne: true };

    // Получаем пользователей с пагинацией
    const users = await User.find(filter)
      .select('-password')
      .skip(skip)
      .limit(parseInt(limit))
      .sort({ createdAt: -1 });

    // Получаем общее количество пользователей для пагинации
    const total = await User.countDocuments(filter);

    res.json({
      users,
      pagination: {
        page: parseInt(page),
        limit: parseInt(limit),
        total,
        pages: Math.ceil(total / limit)
      }
    });
  } catch (error) {
    console.error('Ошибка при получении списка пользователей:', error);
    res.status(500).json({ message: 'Ошибка сервера при получении списка пользователей' });
  }
};

/**
 * @desc    Получить детальную информацию о пользователе
 * @route   GET /api/admin/users/:id
 * @access  Admin
 */
const getUserDetails = async (req, res) => {
  try {
    const userId = req.params.id;
    
    const user = await User.findById(userId)
      .select('-password')
      .lean();
    
    if (!user) {
      return res.status(404).json({ message: 'Пользователь не найден' });
    }

    // Получаем статистику для пользователя
    const messagesCount = await Message.countDocuments({ sender: userId });
    const conversationsCount = await Conversation.countDocuments({ 
      participants: userId 
    });
    const profileViewsCount = await ProfileView.countDocuments({ 
      profileOwner: userId 
    });
    const matchesCount = user.matches ? user.matches.length : 0;
    const likesGivenCount = user.liked ? user.liked.length : 0;

    // Добавляем статистику к данным пользователя
    const userWithStats = {
      ...user,
      stats: {
        messagesCount,
        conversationsCount,
        profileViewsCount,
        matchesCount,
        likesGivenCount
      }
    };

    res.json(userWithStats);
  } catch (error) {
    console.error('Ошибка при получении информации о пользователе:', error);
    res.status(500).json({ message: 'Ошибка сервера при получении информации о пользователе' });
  }
};

/**
 * @desc    Заблокировать/разблокировать пользователя
 * @route   PUT /api/admin/users/:id/toggle-active
 * @access  Admin
 */
const toggleUserActive = async (req, res) => {
  try {
    const userId = req.params.id;
    const user = await User.findById(userId);
    
    if (!user) {
      return res.status(404).json({ message: 'Пользователь не найден' });
    }

    // Проверка, чтобы нельзя было заблокировать админа
    if (user.isAdmin) {
      return res.status(403).json({ message: 'Невозможно заблокировать администратора' });
    }

    // Изменяем статус активности на противоположный
    user.isActive = !user.isActive;
    await user.save();

    res.json({ 
      message: user.isActive ? 'Пользователь разблокирован' : 'Пользователь заблокирован',
      isActive: user.isActive
    });
  } catch (error) {
    console.error('Ошибка при изменении статуса пользователя:', error);
    res.status(500).json({ message: 'Ошибка сервера при изменении статуса пользователя' });
  }
};

/**
 * @desc    Получить статистику приложения
 * @route   GET /api/admin/statistics
 * @access  Admin
 */
const getAppStatistics = async (req, res) => {
  try {
    // Общая статистика пользователей
    const totalUsers = await User.countDocuments({ isAdmin: { $ne: true } });
    const activeUsers = await User.countDocuments({ isActive: true, isAdmin: { $ne: true } });
    const inactiveUsers = await User.countDocuments({ isActive: false, isAdmin: { $ne: true } });
    
    // Статистика по полу
    const maleUsers = await User.countDocuments({ gender: 'male' });
    const femaleUsers = await User.countDocuments({ gender: 'female' });
    const otherGenderUsers = await User.countDocuments({ gender: 'other' });
    
    // Статистика сообщений и диалогов
    const totalMessages = await Message.countDocuments();
    const totalConversations = await Conversation.countDocuments();
    
    // Статистика просмотров профилей
    const totalProfileViews = await ProfileView.countDocuments();
    
    // Средние значения
    const messagesPerUser = totalUsers > 0 ? totalMessages / totalUsers : 0;
    const conversationsPerUser = totalUsers > 0 ? totalConversations / totalUsers : 0;
    
    // Новые пользователи за последние 30 дней
    const thirtyDaysAgo = new Date();
    thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);
    
    const newUsers30Days = await User.countDocuments({ 
      createdAt: { $gte: thirtyDaysAgo },
      isAdmin: { $ne: true }
    });
    
    res.json({
      users: {
        total: totalUsers,
        active: activeUsers,
        inactive: inactiveUsers,
        newIn30Days: newUsers30Days,
        genderDistribution: {
          male: maleUsers,
          female: femaleUsers,
          other: otherGenderUsers
        }
      },
      activity: {
        totalMessages,
        totalConversations,
        totalProfileViews,
        averages: {
          messagesPerUser: messagesPerUser.toFixed(2),
          conversationsPerUser: conversationsPerUser.toFixed(2)
        }
      }
    });
  } catch (error) {
    console.error('Ошибка при получении статистики приложения:', error);
    res.status(500).json({ message: 'Ошибка сервера при получении статистики приложения' });
  }
};

/**
 * @desc    Получить список всех диалогов
 * @route   GET /api/admin/conversations
 * @access  Admin
 */
const getAllConversations = async (req, res) => {
  try {
    const { page = 1, limit = 20, userId } = req.query;
    const skip = (page - 1) * limit;
    
    // Создание фильтра
    const filter = {};
    
    // Фильтр по пользователю, если указан
    if (userId) {
      filter.participants = userId;
    }
    
    // Получаем диалоги с пагинацией и данными участников
    const conversations = await Conversation.find(filter)
      .populate('participants', 'name email photos')
      .populate('lastMessage')
      .skip(skip)
      .limit(parseInt(limit))
      .sort({ updatedAt: -1 });
    
    // Получаем общее количество диалогов для пагинации
    const total = await Conversation.countDocuments(filter);
    
    res.json({
      conversations,
      pagination: {
        page: parseInt(page),
        limit: parseInt(limit),
        total,
        pages: Math.ceil(total / limit)
      }
    });
  } catch (error) {
    console.error('Ошибка при получении списка диалогов:', error);
    res.status(500).json({ message: 'Ошибка сервера при получении списка диалогов' });
  }
};

/**
 * @desc    Получить сообщения диалога
 * @route   GET /api/admin/conversations/:id/messages
 * @access  Admin
 */
const getConversationMessages = async (req, res) => {
  try {
    const conversationId = req.params.id;
    const { page = 1, limit = 50 } = req.query;
    const skip = (page - 1) * limit;
    
    // Проверяем существование диалога
    const conversation = await Conversation.findById(conversationId);
    if (!conversation) {
      return res.status(404).json({ message: 'Диалог не найден' });
    }
    
    // Получаем сообщения с пагинацией
    const messages = await Message.find({ conversationId })
      .populate('sender', 'name email')
      .skip(skip)
      .limit(parseInt(limit))
      .sort({ createdAt: -1 });
    
    // Получаем общее количество сообщений для пагинации
    const total = await Message.countDocuments({ conversationId });
    
    res.json({
      messages,
      pagination: {
        page: parseInt(page),
        limit: parseInt(limit),
        total,
        pages: Math.ceil(total / limit)
      }
    });
  } catch (error) {
    console.error('Ошибка при получении сообщений диалога:', error);
    res.status(500).json({ message: 'Ошибка сервера при получении сообщений диалога' });
  }
};

module.exports = {
  getAllUsers,
  getUserDetails,
  toggleUserActive,
  getAppStatistics,
  getAllConversations,
  getConversationMessages
};