const User = require("../models/user.model");
const bcrypt = require("bcryptjs");
const { sendError } = require("../utils/http");
const { logError } = require("../utils/logger");

exports.test = async (req, res) => {
  res.json({ message: "User route is working" });
};

exports.getAllUsers = async (req, res) => {
  const users = await User.getAllUsers();
  res.json(users);
};


exports.updateUserRole = async (req, res) => {
  try {
    const { id, role } = req.body;
    if (!Object.values(User.ROLES).includes(role))
      return sendError(res, 400, "Invalid role");

    const updated = await User.updateUserRole(id, role);
    if (!updated)
      return sendError(res, 404, "User not found");

    res.json({ message: "Role updated", id, role });
  } catch (err) {
    logError(req, "users.updateUserRole", err);
    sendError(res, 500, "Failed to update role");
  }
};

exports.deleteUser = async (req, res) => {
  try {
    const { id } = req.params;

    const deleted = await User.deleteUser(id);
    if (!deleted)
      return sendError(res, 404, "User not found");


    res.json({ message: "User deleted", id });
  } catch (err) {
    logError(req, "users.deleteUser", err);
    sendError(res, 500, "Failed to delete user");
  }
};

exports.checkIfUserExists = async (req, res) => {
  const { username } = req.query;
  const exists = await User.checkIfUserExists(username);
  res.json(exists);
};

exports.getCurrentUser = async (req, res) => {
  try {
    const userId = req.user.id;
    const user = await User.getUserById(userId);

    if (!user) {
      return sendError(res, 404, "User not found");
    }

    res.json(user);
  } catch (err) {
    logError(req, "users.getCurrentUser", err);
    sendError(res, 500, "Failed to get user profile");
  }
};

exports.updateCurrentUser = async (req, res) => {
  try {
    const userId = req.user.id;
    const { display_name } = req.body;

    if (!display_name || display_name.trim().length === 0) {
      return sendError(res, 400, "Display name is required");
    }

    if (display_name.length > 100) {
      return sendError(res, 400, "Display name must be 100 characters or less");
    }

    const updated = await User.updateUserProfile(userId, { display_name: display_name.trim() });

    if (!updated) {
      return sendError(res, 404, "User not found");
    }

    res.json({ message: "Profile updated successfully", user: updated });
  } catch (err) {
    logError(req, "users.updateCurrentUser", err);
    sendError(res, 500, "Failed to update profile");
  }
};

exports.changePassword = async (req, res) => {
  try {
    const userId = req.user.id;
    const { current_password, new_password } = req.body;

    // Validation
    if (!current_password || !new_password) {
      return sendError(res, 400, "Current password and new password are required");
    }

    if (new_password.length < 6) {
      return sendError(res, 400, "New password must be at least 6 characters");
    }

    // Get current password hash
    const currentHash = await User.getUserPasswordHash(userId);

    if (!currentHash) {
      return sendError(res, 404, "User not found");
    }

    // Verify current password
    const isValidPassword = await bcrypt.compare(current_password, currentHash);

    if (!isValidPassword) {
      return sendError(res, 401, "Current password is incorrect");
    }

    // Hash new password
    const salt = await bcrypt.genSalt(10);
    const hashedPassword = await bcrypt.hash(new_password, salt);

    // Update password
    await User.updateUserPassword(userId, hashedPassword);

    res.json({ message: "Password changed successfully" });
  } catch (err) {
    logError(req, "users.changePassword", err);
    sendError(res, 500, "Failed to change password");
  }
};
