const { sequelize } = require('../../../models/migration')
const response = require('../../helpers/responses')
const errorHandler = require('../../middlewares/errorHandler')
const db = require('../../../models/migration')
const User = db.User
const Branch = db.Branch
const {Op} = require('sequelize')
const bcrypt = require('bcrypt')
const UserResource = require('../resources/user.resource')

const create = async (req, res) => {
    const t = await sequelize.transaction();
    try {
      const { name, email, password, role, phone, branch_id } = req.body;
  
      // Hash password sebelum simpan
      const hashedPassword = password ? await bcrypt.hash(password, 10) : null;
  
      const user = await User.create(
        {
          name,
          email,
          phone,
          branch_id,
          role,
          password: hashedPassword,
        },
        { transaction: t }
      );
  
      await t.commit();
  
      // Jangan kirim password di response
      return response.success(res, new UserResource(user), "Created Successfully");
    } catch (error) {
      await t.rollback();
      errorHandler(error, req, res);
      return response.failed(res, 500, error.message);
    }
  };
  

const index = async (req, res) => {
    try {
        const {search} = req.query
        const where = {}
        if (search) {
            where[Op.or] = [
                {name: { [Op.iLike]: `%${search}%`}},
                {email: { [Op.iLike]: `%${search}%`}},
            ]
        }
        const user = await User.findAll({
            where,
            include: [
                {
                  model: Branch,
                  as: 'branch',
                  attributes: ['name'],
                },
              ],
            order: [['created_at', 'DESC']]
        })
        return response.success(res, UserResource.collection(user), 'Loaded Successfuly')
    } catch (error) {
        errorHandler(error, req, res)
        return response.failed(res, 500, error.message)
    }
}

const update = async (req, res) => {
    const t = await sequelize.transaction()
    try {
        const id = req.params.id
        const {name, email, password, role} = req.body

        const user = await User.findOne({
            where: {id},
            transaction: t
        })

        if (!user) {
            await t.rollback()
            return response.failed(res, 404, 'User not found')
        }

        let hashedPassword = user.password

        if (password) {
            hashedPassword = await bcrypt.hash(password, 10)
        }

        const userUpdate = await user.update({
            name,
            email,
            password: hashedPassword,
            role
        }, {transaction: t})
        await t.commit()
        return response.success(res, new UserResource(userUpdate), 'Update user successfuly')
    } catch (error) {
        await t.rollback()
        errorHandler(error, req, res)
        return response.failed(res, 500, error.message)
    }
}

const destroy = async (req, res) => {
    const t = await sequelize.transaction()
    try {
        const id = req.params.id
        const user = await User.findOne({
            where: {id},
            transaction: t
        })

        if (!user) {
            await t.rollback()
            return response.failed(res, 404, 'User not found')
        }

        await user.destroy({force: true, transaction: t})
        await t.commit()
        return response.success(res, null, 'Delete user successfuly')
    } catch (error) {
        await t.rollback()
        errorHandler(error, req, res)
        return response.failed(res, 500, error.message)
    }
}

const suspend = async (req, res) => {
    const t = await sequelize.transaction()
    try {
        const id = req.params.id
        const user = await User.findByPk(id, {transaction: t})
        if (!user) {
            await t.rollback()
            return response.failed(res, 404, 'User Not Found')
        }
        await user.update({is_suspended: true}, {transaction: t})
        await t.commit()
        return response.success(res, user, 'Suspended Successfuly')
    } catch (error) {
        await t.rollback()
        errorHandler(error, req, res)
        return response.failed(res, 500, error.message)
    }
}

const unsuspend = async (req, res) => {
    const t = await sequelize.transaction()
    try {
        const id = req.params.id
        const user = await User.findByPk(id, {transaction: t})
        if (!user) {
            await t.rollback()
            return response.failed(res, 404, 'User Not Found')
        }
        await user.update({is_suspended: false}, {transaction:t})
        await t.commit()
        return response.success(res, user, 'Unsuspended Successfully')
    } catch (error) {
        await t.rollback()
        errorHandler(error, req, res)
        return response.failed(res, 500, error.message)
    }
}

module.exports = {
    index,
    create,
    update,
    destroy,
    suspend,
    unsuspend
}