'use strict';

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

function bearerToken(req) {
  const header = String(req.headers.authorization || '');
  const match = header.match(/^Bearer\s+(.+)$/i);
  return match ? match[1].trim() : null;
}

async function requireUser(req, res, next) {
  try {
    const token = bearerToken(req);
    if (!token) return res.status(401).json({ message: 'يجب تسجيل الدخول.' });

    const tokenHash = hashToken(token);
    const [rows] = await pool.execute(
      `SELECT s.id AS session_id, u.id, u.username, u.category
       FROM user_sessions s
       INNER JOIN users u ON u.id = s.user_id
       WHERE s.token_hash = ?
       LIMIT 1`,
      [tokenHash],
    );

    if (!rows.length) return res.status(401).json({ message: 'انتهت الجلسة أو تم حذف المستخدم.' });

    const user = rows[0];
    const [permissionRows] = await pool.execute(
      'SELECT menu_key FROM user_permissions WHERE user_id = ? ORDER BY menu_key',
      [user.id],
    );

    req.authTokenHash = tokenHash;
    req.user = {
      id: user.id,
      username: user.username,
      category: user.category,
      permissions: permissionRows.map((row) => row.menu_key),
    };

    pool.execute('UPDATE user_sessions SET last_seen_at = UTC_TIMESTAMP() WHERE id = ?', [user.session_id]).catch(() => {});
    return next();
  } catch (error) {
    return next(error);
  }
}

async function requireAdmin(req, res, next) {
  try {
    const token = bearerToken(req);
    if (!token) return res.status(401).json({ message: 'يجب تسجيل دخول الأدمن.' });

    const tokenHash = hashToken(token);
    const [rows] = await pool.execute(
      `SELECT s.id AS session_id, a.id, a.username
       FROM admin_sessions s
       INNER JOIN admins a ON a.id = s.admin_id
       WHERE s.token_hash = ?
       LIMIT 1`,
      [tokenHash],
    );

    if (!rows.length) return res.status(401).json({ message: 'انتهت جلسة الأدمن.' });

    const admin = rows[0];
    req.authTokenHash = tokenHash;
    req.admin = { id: admin.id, username: admin.username };
    pool.execute('UPDATE admin_sessions SET last_seen_at = UTC_TIMESTAMP() WHERE id = ?', [admin.session_id]).catch(() => {});
    return next();
  } catch (error) {
    return next(error);
  }
}

function requirePermission(menuKey) {
  return function permissionMiddleware(req, res, next) {
    if (!req.user?.permissions?.includes(menuKey)) {
      return res.status(403).json({ message: 'ليس لديك صلاحية لهذه القائمة.' });
    }
    return next();
  };
}

module.exports = { bearerToken, requireUser, requireAdmin, requirePermission };
