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

// NEW: Token authentication middleware
exports.authenticateToken = async (req, res, next) => {
  try {
    const authHeader = req.headers['authorization'];
    const token = authHeader && authHeader.split(' ')[1];
    
    if (!token) {
      return res.status(401).json({ 
        success: false,
        message: 'Access token required | Tokeni inahitajika' 
      });
    }

    // 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({ 
        success: false,
        message: 'Invalid or expired session | Kipindi kimeisha' 
      });
    }

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

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

    // Attach user to request
    req.user = {
      id: user.id,
      email: user.email,
      role: user.role,
      username: user.username
    };
    
    next();
  } catch (error) {
    if (error.name === 'JsonWebTokenError') {
      return res.status(401).json({ 
        success: false,
        message: 'Invalid token | Tokeni si sahihi' 
      });
    }
    if (error.name === 'TokenExpiredError') {
      return res.status(401).json({ 
        success: false,
        message: 'Token expired | Tokeni imeisha' 
      });
    }
    console.error('Authentication error:', error);
    res.status(500).json({ 
      success: false,
      message: 'Authentication failed | Uthibitishaji umeshindikana' 
    });
  }
};

// NEW: Require admin middleware
exports.requireAdmin = (req, res, next) => {
  if (req.user.role !== 'admin') {
    return res.status(403).json({ 
      success: false,
      message: 'Admin access required | Unahitaji kuwa msimamizi' 
    });
  }
  next();
};

// EXISTING: Original authenticate middleware
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, {
      attributes: { exclude: ['password'] }
    });

    if (!user || !user.isActive) {
      return res.status(401).json({ message: 'User not found or inactive' });
    }

    // === NEW: Extract and validate Register ID (for cashiers) ===
    const registerIdHeader = req.headers['x-register-id'];

    if (registerIdHeader) {
      const registerId = parseInt(registerIdHeader);

      if (isNaN(registerId)) {
        return res.status(400).json({ message: 'Invalid register ID' });
      }

      // Find the register
      const register = await Register.findByPk(registerId);

      if (!register) {
        return res.status(400).json({ message: 'Register not found' });
      }

      // Optional: Ensure register belongs to user's store
      const userStoreId = user.storeId || user.store_id;
      if (register.storeId !== userStoreId) {
        return res.status(403).json({
          message: 'This register does not belong to your store'
        });
      }

      // Optional: Check if register is open (recommended for POS routes)
      if (!register.isOpen) {
        return res.status(400).json({ message: 'Register is not open' });
      }

      // Optional: Verify the register was opened by this user (extra security)
      if (register.currentUserId && register.currentUserId !== user.id) {
        return res.status(403).json({
          message: 'This register is currently used by another cashier'
        });
      }

      // Attach register info
      req.registerId = registerId;
      req.register = register; // full register object if needed
    } else {
      // No register ID sent — allowed for non-POS routes or non-cashiers
      req.registerId = null;
      req.register = null;
    }

    // Attach to request
    req.user = user;
    req.session = session;

    // Also attach storeId for convenience (even if not in header)
    const storeIdFromHeader = req.headers['x-store-id'];
    if (storeIdFromHeader) {
      req.storeId = parseInt(storeIdFromHeader);
    } else if (user.storeId || user.store_id) {
      req.storeId = user.storeId || user.store_id;
    }

    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' });
    }
    console.error('Authentication error:', error);
    res.status(500).json({ message: 'Authentication error', error: error.message });
  }
};

// EXISTING: Optional middleware to REQUIRE register for cashier-only routes
exports.requireRegister = (req, res, next) => {
  if (!req.user) {
    return res.status(401).json({ message: 'Authentication required' });
  }

  const isCashier = req.user.role?.toLowerCase() === 'cashier';

  if (isCashier && !req.registerId) {
    return res.status(400).json({
      message: 'Cashier must select and open a register before performing this action'
    });
  }

  next();
};

// EXISTING: Authorization middleware
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();
  };
};

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

    const requestedStoreId = req.headers['x-store-id'];
    if (!requestedStoreId) return next();

    const userStoreId = req.user.storeId || req.user.store_id;
    if (!userStoreId) {
      return res.status(403).json({ message: 'User has no store assigned' });
    }

    if (parseInt(requestedStoreId) !== parseInt(userStoreId)) {
      return res.status(403).json({ message: 'Access denied to this store' });
    }

    req.storeId = parseInt(requestedStoreId);
    next();
  } catch (error) {
    res.status(500).json({ message: 'Store access error' });
  }
};

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

  if (req.user.role === 'admin' || req.user.role === 'super_admin') {
    if (req.headers['x-store-id']) {
      req.storeId = parseInt(req.headers['x-store-id']);
    }
    return next();
  }

  return exports.verifyStoreAccess(req, res, next);
};

// EXISTING: Extract store ID middleware
exports.extractStoreId = (req, res, next) => {
  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();
};