const {pool} = require('../config/db');

const modulePermissionMap = {
  Dashboard: ['dashboard.view'],
  Customers: ['customers.view'],
  Loans: ['loans.view'],
  Reports: ['reports.view'],
  Users: ['users.view'],
  Privileges: ['privileges.view'],
  Settings: ['settings.view'],
};

function toFrontendPermission(moduleName) {
  return moduleName === 'Customers' ? 'Customers' : moduleName;
}

async function getUserFrontendPermissions(userId, roleName) {
  if (roleName === 'Owner') {
    return ['Dashboard', 'Customers', 'Loans', 'Reports', 'Users', 'Privileges', 'Settings'];
  }

  const [rows] = await pool.execute(
    `SELECT DISTINCT p.module_name
     FROM permissions p
     LEFT JOIN user_permissions up ON up.permission_id = p.id AND up.user_id = ?
     INNER JOIN users u ON u.id = ?
     LEFT JOIN role_permissions rp ON rp.permission_id = p.id AND rp.role_id = u.role_id
     WHERE COALESCE(up.is_allowed, IF(rp.permission_id IS NULL, 0, 1)) = 1`,
    [userId, userId],
  );

  return rows.map(row => toFrontendPermission(row.module_name));
}

async function listPrivileges() {
  const [roles] = await pool.execute(
    `SELECT id, role_name AS roleName
     FROM roles
     ORDER BY id`,
  );

  const [permissions] = await pool.execute(
    `SELECT id, permission_key AS permissionKey, permission_name AS permissionName, module_name AS moduleName, action_name AS actionName
     FROM permissions
     ORDER BY module_name, action_name`,
  );

  const [rolePermissions] = await pool.execute(
    `SELECT rp.role_id AS roleId, r.role_name AS roleName, p.permission_key AS permissionKey
     FROM role_permissions rp
     INNER JOIN roles r ON r.id = rp.role_id
     INNER JOIN permissions p ON p.id = rp.permission_id
     ORDER BY r.role_name, p.module_name, p.action_name`,
  );

  return {roles, permissions, rolePermissions};
}

async function saveRolePermissions(roleId, permissionKeys) {
  const connection = await pool.getConnection();
  try {
    await connection.beginTransaction();
    await connection.execute('DELETE FROM role_permissions WHERE role_id = ?', [roleId]);

    if (permissionKeys.length) {
      const [permissions] = await connection.query('SELECT id FROM permissions WHERE permission_key IN (?)', [permissionKeys]);
      if (permissions.length) {
        await connection.query(
          'INSERT INTO role_permissions (role_id, permission_id) VALUES ?',
          [permissions.map(permission => [roleId, permission.id])],
        );
      }
    }

    await connection.commit();
  } catch (error) {
    await connection.rollback();
    throw error;
  } finally {
    connection.release();
  }

  return listPrivileges();
}

module.exports = {getUserFrontendPermissions, listPrivileges, modulePermissionMap, saveRolePermissions};
