// middleware/auth.js
const jwt = require('jsonwebtoken');
const { User, Session } = require('../models');

exports.authenticate = async (req, res, next) => {
  try {
    const token = req.headers.authorization?.split(' ')[1];
    if (!token) {
      return res.status(401).json({ message: 'Authentication required' });
    }

    // Verify token
    const decoded = jwt.verify(token, process.env.JWT_SECRET);

    // Check if session exists
    const session = await Session.findOne({
      where: { token, userId: decoded.id }
    });

    if (!session) {
      return res.status(401).json({ message: 'Invalid or expired session' });
    }

    // Check if session is expired
    if (new Date() > session.expiresAt) {
      await session.destroy();
      return res.status(401).json({ message: 'Session expired' });
    }

    // Get user
    const user = await User.findByPk(decoded.id);
    // console.log('Authenticated user:', user);
    
    if (!user || !user.isActive) {
      return res.status(401).json({ message: 'User not found or inactive' });
    }

    // Attach user to request
    req.user = user;
    req.session = session;
    
    next();
  } catch (error) {
    if (error.name === 'JsonWebTokenError') {
      return res.status(401).json({ message: 'Invalid token' });
    }
    if (error.name === 'TokenExpiredError') {
      return res.status(401).json({ message: 'Token expired' });
    }
    res.status(500).json({ message: 'Authentication error', error: error.message });
  }
};

exports.authorize = (roles) => {
  return (req, res, next) => {
    if (!req.user) {
      return res.status(401).json({ message: 'Authentication required' });
    }

    if (!roles.includes(req.user.role)) {
      return res.status(403).json({
        message: 'Access denied. Insufficient permissions.'
      });
    }

    next();
  };
};

// New middleware: Verify store access
exports.verifyStoreAccess = (req, res, next) => {
  try {
    if (!req.user) {
      return res.status(401).json({ message: 'Authentication required' });
    }

    // Get store ID from header
    const requestedStoreId = req.headers['x-store-id'];
    
    // If no store ID in header, skip this check (backward compatibility)
    if (!requestedStoreId) {
      return next();
    }

    // Get user's store ID
    const userStoreId = req.user.storeId || req.user.store_id;

    // If user has no store assigned, deny access
    if (!userStoreId) {
      return res.status(403).json({ 
        message: 'User is not assigned to any store. Please contact administrator.' 
      });
    }

    // Check if requested store matches user's store
    if (parseInt(requestedStoreId) !== parseInt(userStoreId)) {
      return res.status(403).json({ 
        message: 'Access denied. You do not have permission to access this store.' 
      });
    }

    // Attach store ID to request for use in controllers
    req.storeId = parseInt(requestedStoreId);
    
    next();
  } catch (error) {
    res.status(500).json({ 
      message: 'Store verification error', 
      error: error.message 
    });
  }
};

// Optional: Middleware to verify store access for admins (can access any store)
exports.verifyStoreAccessOrAdmin = (req, res, next) => {
  try {
    if (!req.user) {
      return res.status(401).json({ message: 'Authentication required' });
    }

    // Admins can access any store
    if (req.user.role === 'admin' || req.user.role === 'super_admin') {
      const requestedStoreId = req.headers['x-store-id'];
      if (requestedStoreId) {
        req.storeId = parseInt(requestedStoreId);
      }
      return next();
    }

    // For non-admins, use regular store verification
    exports.verifyStoreAccess(req, res, next);
  } catch (error) {
    res.status(500).json({ 
      message: 'Store verification error', 
      error: error.message 
    });
  }
};

// Helper middleware: Extract store ID from various sources
exports.extractStoreId = (req, res, next) => {
  try {
    // Priority: header > query param > route param > user's default store
    const storeId = 
      req.headers['x-store-id'] || 
      req.query.store_id || 
      req.params.store_id || 
      req.user?.storeId || 
      req.user?.store_id;

    if (storeId) {
      req.storeId = parseInt(storeId);
    }

    next();
  } catch (error) {
    res.status(500).json({ 
      message: 'Error extracting store ID', 
      error: error.message 
    });
  }
};