import jwt from 'jsonwebtoken';
import { UserMaster } from '../models/index.js';

export function requireAuth(req, res, next) {
  try {
    const header = req.headers.authorization || '';
    const token = header.startsWith('Bearer ') ? header.slice(7) : null;
    if (!token) {
      return res.status(401).json({ success: false, message: 'Missing token' });
    }

    const payload = jwt.verify(token, process.env.JWT_SECRET);
    req.user = payload; // { login_id, client_id, treelogy_id?, authority, name }
    next();
  } catch (e) {
    return res.status(401).json({ success: false, message: 'Invalid token' });
  }
  
}

export function requireRole(...allowedRoleNames) {
  return async (req, res, next) => {
    try {
      if (!req.user?.role_id) {
        return res.status(403).json({ success: false, message: 'Forbidden' });
      }
      
      // Get role information from UserMaster table
      const role = await UserMaster.findByPk(req.user.role_id);
      if (!role || !role.is_active || !allowedRoleNames.includes(role.role_name)) {
        return res.status(403).json({ success: false, message: 'Forbidden' });
      }
      
      req.user.role = role; // Add role info to request
      next();
    } catch (error) {
      console.error('Error checking role:', error);
      return res.status(500).json({ success: false, message: 'Internal server error' });
    }
  };
}

export function requireAnyRole(roles) {
  return requireRole(...roles);
}

// Helper function to get roles dynamically from database
export async function getRoles() {
  try {
    const roles = await UserMaster.findAll({
      where: { is_active: true },
      order: [['sort_order', 'ASC']]
    });
    return roles;
  } catch (error) {
    console.error('Error fetching roles:', error);
    return [];
  }
}

// Helper function to get role names
export async function getRoleNames() {
  try {
    const roles = await getRoles();
    return roles.map(role => role.role_name);
  } catch (error) {
    console.error('Error fetching role names:', error);
    return [];
  }
}