// Контроллер аутентификации
const User = require('../models/User');
const jwt = require('jsonwebtoken');
const profanityFilter = require('../utils/profanityFilter');

// Вспомогательная функция для генерации JWT
const generateToken = (id) => {
  return jwt.sign({ id }, process.env.JWT_SECRET, {
    expiresIn: '30d',
  });
};

// @desc    Регистрация нового пользователя
// @route   POST /api/auth/register
// @access  Public
const registerUser = async (req, res, next) => {
  try {
    const { name, email, password, dateOfBirth, gender, city } = req.body;

    console.log('Начало регистрации пользователя с email:', email);

    if (!name || !email || !password || !dateOfBirth) {
      res.status(400);
      throw new Error('Пожалуйста, заполните все обязательные поля: имя, email, пароль и дату рождения.');
    }
    
    // Проверяем наличие города
    if (!city) {
      res.status(400);
      throw new Error('Пожалуйста, выберите город.');
    }

    // Проверка имени на наличие запрещенных слов
    if (await profanityFilter.isProfane(name)) {
      res.status(400);
      throw new Error('Имя содержит запрещённые слова. Пожалуйста, используйте другое имя.');
    }

    // Проверка возраста (минимум 14 лет)
    const birthDate = new Date(dateOfBirth);
    const today = new Date();
    let age = today.getFullYear() - birthDate.getFullYear();
    const monthDiff = today.getMonth() - birthDate.getMonth();
    
    if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) {
      age--;
    }
    
    if (age < 14) {
      res.status(400);
      throw new Error('Для регистрации необходим возраст не менее 14 лет.');
    }

    const normalizedEmail = email.toLowerCase();
    console.log('Нормализованный email для поиска:', normalizedEmail);

    const userExists = await User.findOne({ email: normalizedEmail });

    if (userExists) {
      console.log('Пользователь с таким email уже существует');
      res.status(400);
      throw new Error('Пользователь с таким email уже существует.');
    }

    console.log('Создание нового пользователя...');
    const user = await User.create({
      name,
      email: normalizedEmail,
      password,
      dateOfBirth,
      gender,
      location: { 
        city: city,
        country: 'Россия'  // Устанавливаем страну по умолчанию
      }
    });

    console.log('Пользователь создан успешно:', user ? 'Да' : 'Нет', 'ID:', user ? user._id : 'N/A');

    if (user) {
      res.status(201).json({
        _id: user._id,
        name: user.name,
        email: user.email,
        token: generateToken(user._id),
        message: 'Пользователь успешно зарегистрирован!'
      });
    } else {
      res.status(400);
      throw new Error('Неверные данные пользователя. Не удалось создать пользователя.');
    }
  } catch (error) {
    console.error('Ошибка при регистрации:', error.message);
    if (!res.statusCode || res.statusCode < 400) {
        res.status(400);
    }
    res.json({ message: error.message, stack: process.env.NODE_ENV === 'production' ? null : error.stack });
  }
};

// @desc    Аутентификация пользователя и получение токена (Вход)
// @route   POST /api/auth/login
// @access  Public
const loginUser = async (req, res, next) => {
  try {
    const { email, password } = req.body;

    console.log('Попытка входа с email/логином:', email);

    if (!email || !password) {
      res.status(400);
      throw new Error('Пожалуйста, укажите email и пароль.');
    }    // Проверяем наличие специального логина для администратора
    if (email === 'admin') {
      // Для логина "admin" проверяем аккаунт admin@example.com
      console.log('Попытка входа с административным логином через "admin"');
      const user = await User.findOne({ email: 'admin@example.com' }).select('+password');

      if (!user) {
        console.log('Административный аккаунт не найден в базе данных');
        console.log('Создание административного аккаунта...');
        
        try {
          // Если админ не найден, создаем его с валидным email
          const adminUser = new User({
            name: 'Администратор',
            email: 'admin@example.com', // Используем валидный email
            password: 'admin124', // Пароль будет хеширован pre-save hook
            dateOfBirth: new Date('1990-01-01'),
            gender: 'other',
            isActive: true,
            isAdmin: true,
            location: {
              city: 'Admin',
              country: 'System'
            }
          });
          
          await adminUser.save();
          console.log('Административный аккаунт создан успешно');
          
          res.status(200).json({
            _id: adminUser._id,
            name: adminUser.name,
            email: adminUser.email,
            isAdmin: true,
            token: generateToken(adminUser._id),
            message: 'Административный аккаунт создан. Вход выполнен успешно!'
          });
          return;
        } catch (adminError) {
          console.error('Ошибка при создании админ-аккаунта:', adminError);
          res.status(401);
          throw new Error('Неверный логин или пароль. Не удалось создать админа автоматически.');
        }
      }

      if (!user.password) {
        console.error('Ошибка: Пароль не загружен из базы данных для административного аккаунта');
        res.status(500);
        throw new Error('Внутренняя ошибка сервера при проверке учетных данных.');
      }

      console.log('Проверка пароля для административного аккаунта...');
      const isMatch = await user.matchPassword(password);
      console.log('Результат проверки пароля:', isMatch ? 'Успешно' : 'Неверный пароль');

      if (isMatch) {
        // Обновляем дату последнего входа
        user.lastSeen = new Date();
        await user.save();

        res.status(200).json({
          _id: user._id,
          name: user.name,
          email: user.email,
          isAdmin: user.isAdmin || false,
          token: generateToken(user._id),
          message: 'Вход выполнен успешно!'
        });
      } else {
        res.status(401);
        throw new Error('Неверный логин или пароль.');
      }
      return;
    }    // Перед проверкой обычных пользователей, проверим наличие админа с email
    if (email === 'admin@example.com') {
      console.log('Попытка входа с email администратора: admin@example.com');
      // Проверяем наличие админа с email admin@example.com
      const adminUser = await User.findOne({ email: 'admin@example.com' }).select('+password');
      
      if (adminUser && await adminUser.matchPassword(password)) {
        console.log('Успешный вход через email администратора');
        // Обновляем дату последнего входа
        adminUser.lastSeen = new Date();
        await adminUser.save();
        
        res.status(200).json({
          _id: adminUser._id,
          name: adminUser.name,
          email: adminUser.email,
          isAdmin: true,
          token: generateToken(adminUser._id),
          message: 'Вход выполнен успешно!'
        });
        return;
      }
    }
    
    // Для обычных пользователей продолжаем проверку email
    const normalizedEmail = email.toLowerCase();
    console.log('Нормализованный email для поиска:', normalizedEmail);

    const user = await User.findOne({ email: normalizedEmail }).select('+password');

    console.log('Найден пользователь:', user ? 'Да' : 'Нет');
    console.log('Пользователь содержит пароль:', user && user.password ? 'Да' : 'Нет');
    
    if (!user) {
      console.log('Пользователь не найден в базе данных');
      res.status(401);
      throw new Error('Неверный email или пароль.');
    }
    
    if (!user.password) {
      console.error('Ошибка: Пароль не загружен из базы данных');
      res.status(500);
      throw new Error('Внутренняя ошибка сервера при проверке учетных данных.');
    }

    console.log('Проверка пароля...');
    const isMatch = await user.matchPassword(password);
    console.log('Результат проверки пароля:', isMatch ? 'Успешно' : 'Неверный пароль');

    // Проверка если аккаунт неактивен (заблокирован)
    if (isMatch && !user.isActive && !user.isAdmin) {
      res.status(403);
      throw new Error('Ваш аккаунт заблокирован. Пожалуйста, обратитесь в поддержку.');
    }

    if (isMatch) {
      res.status(200).json({
        _id: user._id,
        name: user.name,
        email: user.email,
        isAdmin: user.isAdmin || false, // Добавляем информацию о правах администратора
        token: generateToken(user._id),
        message: 'Вход выполнен успешно!'
      });
    } else {
      res.status(401);
      throw new Error('Неверный email или пароль.');
    }
  } catch (error) {
    console.error('Ошибка при входе:', error.message);
    if (!res.statusCode || res.statusCode < 400) {
        res.status(401);
    }
    res.json({ message: error.message, stack: process.env.NODE_ENV === 'production' ? null : error.stack });
  }
};

// @desc    Получение данных профиля текущего пользователя
// @route   GET /api/auth/me
// @access  Private
const getMe = async (req, res, next) => {
  try {
    if (!req.user) {
      res.status(404);
      throw new Error('Пользователь не найден.');
    }
    
    res.status(200).json({
      _id: req.user._id,
      name: req.user.name,
      email: req.user.email,
      dateOfBirth: req.user.dateOfBirth,
      gender: req.user.gender,
      bio: req.user.bio,
      photos: req.user.photos,
      location: req.user.location,
      preferences: req.user.preferences,
      isAdmin: req.user.isAdmin || false, // Добавляем информацию об административных правах
      createdAt: req.user.createdAt,
      updatedAt: req.user.updatedAt,
    });
  } catch (error) {
    console.error('Ошибка при получении данных пользователя:', error.message);
    if (!res.statusCode || res.statusCode < 400) {
      res.status(500);
    }
    res.json({ message: error.message, stack: process.env.NODE_ENV === 'production' ? null : error.stack });
  }
};

// Экспортируем все функции
module.exports = {
  registerUser,
  loginUser,
  getMe
};