const bcrypt = require('bcryptjs');
const { User } = require('../models');
const { sendPush, createInAppNotification } = require('../services/PushNotificationService');
const { PushToken } = require('../models');

class UserController {
  async getAll(req, res, next) {
    try {
      const users = await User.findAll({
        attributes: { exclude: ['password_hash', 'reset_password_token', 'reset_password_expires'] },
        order: [['created_at', 'DESC']],
      });
      res.json({ users });
    } catch (error) {
      next(error);
    }
  }

  async getById(req, res, next) {
    try {
      const user = await User.findByPk(req.params.id, {
        attributes: { exclude: ['password_hash', 'reset_password_token', 'reset_password_expires'] },
      });
      if (!user) return res.status(404).json({ error: 'User not found' });
      res.json({ user });
    } catch (error) {
      next(error);
    }
  }

  async update(req, res, next) {
    try {
      const user = await User.findByPk(req.params.id);
      if (!user) return res.status(404).json({ error: 'User not found' });

      const { username, email, full_name, phone, role, is_active, password, block_reason } = req.body;

      if (username && username !== user.username) {
        const existing = await User.findOne({ where: { username } });
        if (existing) return res.status(400).json({ error: 'Username already taken' });
      }
      if (email && email !== user.email) {
        const existing = await User.findOne({ where: { email } });
        if (existing) return res.status(400).json({ error: 'Email already taken' });
      }

      const updates = {};
      if (username) updates.username = username;
      if (email) updates.email = email;
      if (full_name) updates.full_name = full_name;
      if (phone !== undefined) updates.phone = phone;
      if (role) updates.role = role;
      if (is_active !== undefined) updates.is_active = is_active;
      if (block_reason !== undefined) updates.block_reason = block_reason;
      if (password) updates.password_hash = await bcrypt.hash(password, 10);

      const wasActive = user.is_active;
      await user.update(updates);

      if (wasActive && is_active === false) {
        const reason = block_reason || 'Your account has been deactivated by management.';
        const tokens = await PushToken.findAll({ where: { email: user.email } });
        for (const t of tokens) {
          await sendPush(t.token, 'Account Blocked', reason, { type: 'account_blocked', screen: 'Blocked' });
        }
        await createInAppNotification(user.email, user.id, 'account_blocked', 'Account Blocked', reason, { screen: 'Blocked' });
        const EmailService = require('../services/EmailService');
        await EmailService.sendEmail(
          user.email,
          'Account Blocked - Tok Tokkie Shuttles',
          `<p>Hi ${user.full_name},</p><p>Your account has been blocked.</p><p><strong>Reason:</strong> ${reason}</p><p>If you believe this is a mistake, please contact us at <a href="mailto:ronald@shuttlesnamibia.com">ronald@shuttlesnamibia.com</a>.</p>`
        );
      }

      if (!wasActive && is_active === true) {
        const tokens = await PushToken.findAll({ where: { email: user.email } });
        for (const t of tokens) {
          await sendPush(t.token, 'Account Reactivated', 'Your account has been reactivated. You can now log in.', { type: 'account_reactivated' });
        }
        await createInAppNotification(user.email, user.id, 'account_reactivated', 'Account Reactivated', 'Your account has been reactivated. You can now log in.');
      }

      const updated = await User.findByPk(user.id, {
        attributes: { exclude: ['password_hash', 'reset_password_token', 'reset_password_expires'] },
      });
      res.json({ message: 'User updated', user: updated });
    } catch (error) {
      next(error);
    }
  }

  async delete(req, res, next) {
    try {
      const user = await User.findByPk(req.params.id);
      if (!user) return res.status(404).json({ error: 'User not found' });
      if (user.id === req.user.id) return res.status(400).json({ error: 'Cannot delete yourself' });
      await user.destroy();
      res.json({ message: 'User deleted' });
    } catch (error) {
      next(error);
    }
  }
}

module.exports = new UserController();
