const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const userRepo = require('../repositories/userRepository');
const { successResponse, errorResponse } = require('../utils/helpers');
const { logAudit } = require('../middleware/auditLog');

async function login(req, res, next) {
  try {
    const { username, password } = req.body;
    if (!username || !password) return errorResponse(res, 'Username and password required', 400);

    const user = await userRepo.findByUsername(username);
    if (!user || !user.is_active) return errorResponse(res, 'Invalid credentials', 401);

    const valid = await bcrypt.compare(password, user.password);
    if (!valid) return errorResponse(res, 'Invalid credentials', 401);

    const token = jwt.sign(
      { id: user.id, username: user.username, role: user.role, name: user.name },
      process.env.JWT_SECRET,
      { expiresIn: process.env.JWT_EXPIRES_IN || '8h' }
    );

    await logAudit({ userId: user.id, action: 'login', entity: 'users', entityId: user.id, req });
    return successResponse(res, { token, user: { id: user.id, name: user.name, username: user.username, role: user.role } });
  } catch (err) { next(err); }
}

async function me(req, res, next) {
  try {
    const user = await userRepo.findById(req.user.id);
    if (!user) return errorResponse(res, 'User not found', 404);
    return successResponse(res, user);
  } catch (err) { next(err); }
}

async function changePassword(req, res, next) {
  try {
    const { current_password, new_password } = req.body;
    const user = await userRepo.findByUsername(req.user.username);
    if (!user) return errorResponse(res, 'User not found', 404);
    const valid = await bcrypt.compare(current_password, user.password);
    if (!valid) return errorResponse(res, 'Current password is incorrect', 400);
    if (new_password.length < 6) return errorResponse(res, 'New password must be at least 6 characters', 400);
    const hash = await bcrypt.hash(new_password, parseInt(process.env.BCRYPT_ROUNDS) || 10);
    await userRepo.update(user.id, { password: hash });
    await logAudit({ userId: user.id, action: 'change_password', entity: 'users', entityId: user.id, req });
    return successResponse(res, null, 'Password changed successfully');
  } catch (err) { next(err); }
}

module.exports = { login, me, changePassword };
