/**
 * Language Detection Middleware
 * Detects user's preferred language from request headers or user preferences
 */

const User = require('../models/User');
const { verifyToken } = require('../utils/jwt');

// Supported languages
const SUPPORTED_LANGUAGES = ['zh', 'en', 'pt'];
const DEFAULT_LANGUAGE = 'zh';

/**
 * Parse Accept-Language header to get preferred language
 * @param {string} acceptLanguage - Accept-Language header value
 * @returns {string} - Detected language code
 */
const parseAcceptLanguage = (acceptLanguage) => {
  if (!acceptLanguage) return null;

  // Parse Accept-Language header (e.g., "en-US,en;q=0.9,zh;q=0.8")
  const languages = acceptLanguage
    .split(',')
    .map(lang => {
      const [code, qValue] = lang.trim().split(';q=');
      return {
        code: code.split('-')[0].toLowerCase(), // Get base language code
        quality: qValue ? parseFloat(qValue) : 1.0,
      };
    })
    .sort((a, b) => b.quality - a.quality);

  // Find first supported language
  for (const lang of languages) {
    if (SUPPORTED_LANGUAGES.includes(lang.code)) {
      return lang.code;
    }
  }

  return null;
};

/**
 * Language detection middleware
 * Sets req.language based on:
 * 1. X-Language header (explicit override)
 * 2. User's stored preference (if authenticated)
 * 3. Accept-Language header
 * 4. Default language (Chinese)
 */
const languageMiddleware = async (req, res, next) => {
  try {
    let language = null;

    // 1. Check X-Language header (highest priority)
    const xLanguage = req.headers['x-language'];
    if (xLanguage && SUPPORTED_LANGUAGES.includes(xLanguage.toLowerCase())) {
      language = xLanguage.toLowerCase();
    }

    // 2. Check user's stored preference (if authenticated and no explicit header)
    if (!language) {
      const authHeader = req.headers.authorization;
      if (authHeader && authHeader.startsWith('Bearer ')) {
        try {
          const token = authHeader.substring(7);
          const decoded = verifyToken(token);
          
          if (decoded.type === 'user' && decoded.userId) {
            const user = await User.findByPk(decoded.userId, {
              attributes: ['language'],
            });
            
            if (user && user.language) {
              language = user.language;
            }
          }
        } catch (error) {
          // Token verification failed, continue with other methods
        }
      }
    }

    // 3. Check Accept-Language header
    if (!language) {
      language = parseAcceptLanguage(req.headers['accept-language']);
    }

    // 4. Fall back to default language
    if (!language) {
      language = DEFAULT_LANGUAGE;
    }

    // Set language on request object
    req.language = language;
    
    // Also set response header for client awareness
    res.setHeader('Content-Language', language);

    next();
  } catch (error) {
    // On any error, use default language and continue
    req.language = DEFAULT_LANGUAGE;
    res.setHeader('Content-Language', DEFAULT_LANGUAGE);
    next();
  }
};

/**
 * Validate language code
 * @param {string} language - Language code to validate
 * @returns {boolean} - Whether the language is supported
 */
const isValidLanguage = (language) => {
  return SUPPORTED_LANGUAGES.includes(language);
};

/**
 * Get language with fallback
 * @param {string} language - Requested language
 * @returns {string} - Valid language code
 */
const getLanguageWithFallback = (language) => {
  if (language && SUPPORTED_LANGUAGES.includes(language)) {
    return language;
  }
  return DEFAULT_LANGUAGE;
};

module.exports = {
  languageMiddleware,
  parseAcceptLanguage,
  isValidLanguage,
  getLanguageWithFallback,
  SUPPORTED_LANGUAGES,
  DEFAULT_LANGUAGE,
};
