import jwt from 'jsonwebtoken';
import { userDb, settingsDb } from '../database/db.js';

// Get JWT secret from environment or use default (for development)
const JWT_SECRET = process.env.JWT_SECRET || 'claude-ui-dev-secret-change-in-production';

// Optional API key middleware
const validateApiKey = (req, res, next) => {
  // Skip API key validation if not configured
  if (!process.env.API_KEY) {
    return next();
  }
  
  const apiKey = req.headers['x-api-key'];
  if (apiKey !== process.env.API_KEY) {
    return res.status(401).json({ error: 'Invalid API key' });
  }
  next();
};

// JWT authentication middleware
const authenticateToken = async (req, res, next) => {
  const authHeader = req.headers['authorization'];
  const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN

  if (!token) {
    return res.status(401).json({ error: 'Access denied. No token provided.' });
  }

  try {
    const decoded = jwt.verify(token, JWT_SECRET);

    // Check if token was issued before a global session invalidation
    const invalidatedBefore = settingsDb.get('sessions_invalidated_before');
    if (invalidatedBefore && decoded.iat * 1000 < new Date(invalidatedBefore).getTime()) {
      return res.status(401).json({ error: 'Session has been invalidated. Please log in again.' });
    }

    // Verify user still exists and is active
    const user = userDb.getUserById(decoded.userId);
    if (!user) {
      return res.status(401).json({ error: 'Invalid token. User not found.' });
    }

    // Check user status
    if (user.status === 'disabled') {
      return res.status(401).json({ error: 'Account has been disabled' });
    }

    req.user = user;
    next();
  } catch (error) {
    console.error('Token verification error:', error);
    return res.status(403).json({ error: 'Invalid token' });
  }
};

// Generate JWT token with 30-day expiration
const generateToken = (user) => {
  return jwt.sign(
    {
      userId: user.id,
      username: user.username || user.email,
      email: user.email,
      uuid: user.uuid,
      role: user.role
    },
    JWT_SECRET,
    { expiresIn: '30d' } // 30-day expiration
  );
};

// WebSocket authentication function
const authenticateWebSocket = (token) => {
  if (!token) {
    return null;
  }

  try {
    const decoded = jwt.verify(token, JWT_SECRET);

    // Check if token was issued before a global session invalidation
    const invalidatedBefore = settingsDb.get('sessions_invalidated_before');
    if (invalidatedBefore && decoded.iat * 1000 < new Date(invalidatedBefore).getTime()) {
      return null;
    }

    return decoded;
  } catch (error) {
    console.error('WebSocket token verification error:', error);
    return null;
  }
};

export {
  validateApiKey,
  authenticateToken,
  generateToken,
  authenticateWebSocket,
  JWT_SECRET
};