const express = require('express');
const bcrypt = require('bcryptjs');
const { audit, now, one, run } = require('../db');
const { getProfile, savePreferences } = require('../services/profile');
const {
  describe, getPolicy, minAgeRemainingMinutes, recordPassword, validatePassword
} = require('../services/passwordPolicy');

const router = express.Router();

router.get('/profile', (req, res) => {
  res.json({ ...getProfile(req.user), passwordPolicy: { rules: describe() } });
});

router.put('/profile', (req, res) => {
  const preferences = savePreferences(req.user.id, req.body.preferences || {});
  audit(req.user.id, 'update', 'profile_preferences', req.user.id, null, { preferences });
  res.json({ user: getProfile(req.user).user, preferences });
});

// Self-service password change. Honors the configured policy (complexity, identifiers, history,
// and minimum age), then clears any forced-change flag.
router.put('/profile/password', (req, res, next) => {
  try {
    const { current_password: current, new_password: next } = req.body || {};
    const user = one('SELECT * FROM users WHERE id = ?', [req.user.id]);
    if (!user || !bcrypt.compareSync(current || '', user.password_hash)) {
      return res.status(400).json({ error: 'Your current password is incorrect' });
    }
    // The minimum-age rule never blocks a forced change (expired / admin-required).
    const remaining = minAgeRemainingMinutes(user, getPolicy());
    if (remaining > 0 && !user.must_change_password) {
      return res.status(400).json({ error: `You can change your password again in ${remaining} minute(s)` });
    }
    validatePassword(next, { id: user.id, name: user.name, email: user.email });
    const hash = bcrypt.hashSync(next, 12);
    run('UPDATE users SET password_hash = ?, password_changed_at = ?, must_change_password = 0, updated_at = ? WHERE id = ?', [
      hash, now(), now(), user.id
    ]);
    recordPassword(user.id, hash);
    audit(user.id, 'password_change', 'user', user.id, null, { self: true });
    return res.json({ ok: true });
  } catch (error) {
    return next(error);
  }
});

module.exports = router;
