const jwt = require('jsonwebtoken');
const {pool} = require('../config/db');
const {env} = require('../config/env');
const {failure} = require('../utils/apiResponse');

async function authenticate(req, res, next) {
  const header = req.headers.authorization || '';
  const token = header.startsWith('Bearer ') ? header.slice(7) : null;

  if (!token) {
    return failure(res, 401, 'Authentication token is required');
  }

  try {
    const payload = jwt.verify(token, env.jwt.secret);
    const [rows] = await pool.execute(
      `SELECT u.id, u.shop_id, u.username, u.name, u.status, r.role_name
       FROM users u
       INNER JOIN roles r ON r.id = u.role_id
       WHERE u.id = ? AND u.deleted_at IS NULL
       LIMIT 1`,
      [payload.sub],
    );

    if (!rows.length || rows[0].status !== 'Active') {
      return failure(res, 401, 'Session expired');
    }

    req.user = rows[0];
    return next();
  } catch (error) {
    return failure(res, 401, 'Session expired');
  }
}

function requirePermission(permissionKey) {
  return async (req, res, next) => {
    if (req.user.role_name === 'Owner') {
      return next();
    }

    const [rows] = await pool.execute(
      `SELECT p.id
       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 p.permission_key = ?
         AND COALESCE(up.is_allowed, IF(rp.permission_id IS NULL, 0, 1)) = 1
       LIMIT 1`,
      [req.user.id, req.user.id, permissionKey],
    );

    if (!rows.length) {
      return failure(res, 403, 'You do not have permission to perform this action');
    }

    return next();
  };
}

module.exports = {authenticate, requirePermission};
