const { body, validationResult } = require("express-validator");
const bcrypt = require('bcryptjs');
const db = require("../models");
const jwt = require('jsonwebtoken');
const { sendError } = require("../libs/errorCapture");
const { logger } = require("nodejs-log-agent");

exports.validateAdd = [
    body('name').notEmpty().withMessage('Name cannot be empty'),
    body('username').notEmpty().withMessage('Username cannot be empty'),
    body('password').notEmpty().withMessage('Password cannot be empty'),
    body('role').notEmpty().withMessage('Role cannot be empty'),
]
exports.validateUpdate = [
    body('name').notEmpty().withMessage('Name cannot be empty'),
    body('username').notEmpty().withMessage('Username cannot be empty'),
    body('role').notEmpty().withMessage('Role cannot be empty'),
]

exports.validateLogin = [
    body('username').notEmpty().withMessage('Username cannot be empty'),
    body('password').notEmpty().withMessage('Password cannot be empty'),
]
exports.register = async (req, res) => {
    const error = validationResult(req)
    if (!error.isEmpty()) {
        logger.error("validation error on register user", { message : error.message , stack : error.stack, error : error });
        sendError({
            message : "validation error",
            error : error.array()
        })
        return res.json({ 
            status : false,
            message: 'validation error',
            error: error.array() 
        })
    }
    const { name, username, password, role } = req.body;
    try {
        const hashedPassword = await bcrypt.hash(password, 10);
        const user = await db.user.create({ name, username, password: hashedPassword, role });
        res.json({
            status : true,
            message : "user created successfully",
            data : user
        })   
    } catch (error) {
        logger.error("function register user", { message : error.message , stack : error.stack, error : error });
        sendError(error.message)
        res.json({
            status : false,
            message : error.message,
            error
        })
    }
}
exports.update = async (req, res) => {
    const error = validationResult(req)
    if (!error.isEmpty()) {
        logger.error("validation error on update user", { message : error.message , stack : error.stack, error : error });
        sendError({
            message : "validation error",
            error : error.array()
        })
        return res.json({ 
            status : false,
            message: 'validation error',
            error: error.array() 
        })
    }
    const { id, name, username, password, role } = req.body;
    try {
        const params = { name, username, role }
        if (password) {
            const hashedPassword = await bcrypt.hash(password, 10);
            params.password = hashedPassword
        }
        const user = await db.user.update(params, { where: { id: id } });
        res.json({
            status : true,
            message : "user updated successfully",
        })   
    } catch (error) {
        logger.error("function update user", { message : error.message , stack : error.stack, error : error });
        sendError(error.message)
        res.json({
            status : false,
            message : error.message,
            error
        })
    }
}

exports.login = async (req, res) => {
    const { username, password } = req.body;
    const error = validationResult(req)
    if (!error.isEmpty()) {
        logger.error("validation error on login user", { message : error.message , stack : error.stack, error : error });
        sendError({
            message : "validation error",
            error : error.array()
        })
        return res.json({ 
            status : false,
            message: 'validation error',
            error: error.array() 
        })
    }
    try {
        const user = await db.user.findOne({ 
            where: { username }, 
        });
        if (!user) {
            logger.error("user not found", { message : "user not found" });
            return res.json({
                status : false,
                message : "user not found"
            })
        }

        const isMatch = await bcrypt.compare(password, user.password);

        if (!isMatch) {
            return res.json({
                status : false,
                message : "password is incorrect"
            })
        }
        const payload = {
            user_id : user.id,
            role : user.role,
        }
        const token = jwt.sign(payload, process.env.JWT_SECRET || 'antkey24', { expiresIn: '8h' });
        res.json({
            status : true,
            message : "user logged in successfully",
            token,
            name : user.name
        })
    } catch (error) {
        logger.error("function login user", { message : error.message , stack : error.stack, error : error });
        sendError(error.message)
        res.json({
            status : false,
            message : error.message,
            error
        })
    }
}

exports.get = async (req, res) => {
    try {
        const users = await db.user.findAll({
            attributes : ['id', 'name', 'username', 'role']
        });
        res.json({
            status : true,
            message : "users fetched successfully",
            data : users
        })
    } catch (error) {
        logger.error("function get users", { message : error.message , stack : error.stack, error : error });
        sendError(error.message)
        res.json({
            status : false,
            message : error.message,
            error
        })
    }
}
exports.getrole = async (req, res) => {
    try {
        const users = await db.user.findAll({
            where : {
                name : req.params.name
            },
            attributes : ['name', 'role']
        });
        res.json({
            status : true,
            message : "users role fetched successfully",
            data : users
        })
    } catch (error) {
        logger.error("function get users role", { message : error.message , stack : error.stack, error : error });
        sendError(error.message)
        res.json({
            status : false,
            message : error.message,
            error
        })
    }
}

exports.destroy = async (req, res) => {
    const { id } = req.params
    try {
        const user = await db.user.destroy({
            where : {
                id : id
            }
        })
        return res.json({
            status :true,
            message : "delete Successfully"
        });
    } catch (error) {
        logger.error("function delete user", { message : error.message , stack : error.stack, error : error });
        sendError(error.message)
        res.json({
            status: false,
            message: error.message,
            error
        });
    }
}