/**
 * Configuration Reader Service
 * Reads admin configurations from database for use in backend logic
 */

import { sequelize } from '@config/database';
import { QueryTypes } from 'sequelize';
import logger from '@utils/logger';

// Cache configurations in memory for performance
let configCache: Map<string, string> = new Map();
let cacheExpiry: Date | null = null;
const CACHE_DURATION_MS = 5 * 60 * 1000; // 5 minutes

// Sensitive config keys that should be masked in logs
const SENSITIVE_CONFIG_PATTERNS = [
  'API_KEY', 'SECRET', 'PASSWORD', 'TOKEN', 'CREDENTIAL', 
  'PRIVATE', 'AUTH', 'KEY', 'VAPID'
];

/**
 * Check if a config key contains sensitive data
 */
function isSensitiveConfig(configKey: string): boolean {
  const upperKey = configKey.toUpperCase();
  return SENSITIVE_CONFIG_PATTERNS.some(pattern => upperKey.includes(pattern));
}

/**
 * Mask sensitive value for logging (show first 4 and last 2 chars)
 */
function maskSensitiveValue(value: string): string {
  if (!value || value.length <= 8) {
    return '***REDACTED***';
  }
  return `${value.substring(0, 4)}****${value.substring(value.length - 2)}`;
}

/**
 * Get a configuration value from database (with caching)
 */
export async function getConfigValue(configKey: string, defaultValue: string = ''): Promise<string> {
  try {
    // Check cache first
    if (configCache.has(configKey) && cacheExpiry && new Date() < cacheExpiry) {
      return configCache.get(configKey)!;
    }

    // Query database
    const result = await sequelize.query(`
      SELECT config_value 
      FROM admin_configurations 
      WHERE config_key = :configKey
      LIMIT 1
    `, {
      replacements: { configKey },
      type: QueryTypes.SELECT
    });

    if (result && result.length > 0) {
      const value = (result[0] as any).config_value;
      configCache.set(configKey, value);
      
      // Always update cache expiry when loading from database
      cacheExpiry = new Date(Date.now() + CACHE_DURATION_MS);
      
      // Mask sensitive values in logs for security
      const logValue = isSensitiveConfig(configKey) ? maskSensitiveValue(value) : value;
      logger.info(`[ConfigReader] Loaded config '${configKey}' = '${logValue}' from database (cached for 5min)`);
      
      return value;
    }

    // Mask sensitive default values in logs for security
    const logDefault = isSensitiveConfig(configKey) ? maskSensitiveValue(defaultValue) : defaultValue;
    logger.warn(`[ConfigReader] Config key '${configKey}' not found, using default: ${logDefault}`);
    return defaultValue;
  } catch (error) {
    logger.error(`[ConfigReader] Error reading config '${configKey}':`, error);
    return defaultValue;
  }
}

/**
 * Get number configuration
 */
export async function getConfigNumber(configKey: string, defaultValue: number): Promise<number> {
  const value = await getConfigValue(configKey, String(defaultValue));
  return parseFloat(value) || defaultValue;
}

/**
 * Get boolean configuration
 */
export async function getConfigBoolean(configKey: string, defaultValue: boolean): Promise<boolean> {
  const value = await getConfigValue(configKey, String(defaultValue));
  return value === 'true' || value === '1';
}

/**
 * Get TAT thresholds from database
 */
export async function getTatThresholds(): Promise<{ first: number; second: number }> {
  const first = await getConfigNumber('TAT_REMINDER_THRESHOLD_1', 50);
  const second = await getConfigNumber('TAT_REMINDER_THRESHOLD_2', 75);
  
  return { first, second };
}

/**
 * Get working hours from database
 */
export async function getWorkingHours(): Promise<{ startHour: number; endHour: number }> {
  const startHour = await getConfigNumber('WORK_START_HOUR', 9);
  const endHour = await getConfigNumber('WORK_END_HOUR', 18);
  
  return { startHour, endHour };
}

/**
 * Clear configuration cache (call after updating configs)
 */
export function clearConfigCache(): void {
  configCache.clear();
  cacheExpiry = null;
  logger.info('[ConfigReader] Configuration cache cleared');
}

/**
 * Preload all configurations into cache
 */
export async function preloadConfigurations(): Promise<void> {
  try {
    const results = await sequelize.query(`
      SELECT config_key, config_value 
      FROM admin_configurations
    `, { type: QueryTypes.SELECT });

    results.forEach((row: any) => {
      configCache.set(row.config_key, row.config_value);
    });

    cacheExpiry = new Date(Date.now() + CACHE_DURATION_MS);
    logger.info(`[ConfigReader] Preloaded ${results.length} configurations into cache`);
  } catch (error) {
    logger.error('[ConfigReader] Error preloading configurations:', error);
  }
}

/**
 * Get Vertex AI configurations
 */
export async function getVertexAIConfig(): Promise<{
  enabled: boolean;
}> {
  const enabled = await getConfigBoolean('AI_ENABLED', true);
  
  return { enabled };
}

