/**
 * Backward Compatibility Layer
 * Provides dual-mode operation (JSON files or Database)
 * Controlled by USE_JSON_DATABASE environment variable
 */

const fs = require('fs').promises;
const fsSync = require('fs');
const path = require('path');
const { isDatabaseInitialized } = require('./connection');

const USE_JSON_MODE = process.env.USE_JSON_DATABASE === '1' || process.env.USE_JSON_DATABASE === 'true';

// In-memory storage for JSON mode
let jsonUsers = [];
let jsonSessions = new Map();
let jsonAffiliates = [];

/**
 * Check if running in JSON mode
 * @returns {boolean}
 */
function isJsonMode() {
  return USE_JSON_MODE;
}

/**
 * Check if database is available
 * @returns {boolean}
 */
function isDatabaseMode() {
  return !USE_JSON_MODE && isDatabaseInitialized();
}

/**
 * Get storage mode description
 * @returns {string}
 */
function getStorageMode() {
  if (USE_JSON_MODE) {
    return 'JSON (backward compatibility)';
  }
  if (isDatabaseInitialized()) {
    return 'Database (SQLite with encryption)';
  }
  return 'Not initialized';
}

/**
 * Load JSON data for backward compatibility
 * @param {string} filePath - Path to JSON file
 * @param {*} defaultValue - Default value if file doesn't exist
 * @returns {Promise<*>} Parsed JSON data
 */
async function loadJsonFile(filePath, defaultValue = []) {
  try {
    const data = await fs.readFile(filePath, 'utf8');
    return JSON.parse(data);
  } catch (error) {
    if (error.code === 'ENOENT') {
      return defaultValue;
    }
    throw error;
  }
}

/**
 * Save JSON data for backward compatibility
 * @param {string} filePath - Path to JSON file
 * @param {*} data - Data to save
 * @returns {Promise<void>}
 */
async function saveJsonFile(filePath, data) {
  // Ensure directory exists
  const dir = path.dirname(filePath);
  if (!fsSync.existsSync(dir)) {
    await fs.mkdir(dir, { recursive: true });
  }
  
  const tempPath = filePath + '.tmp';
  await fs.writeFile(tempPath, JSON.stringify(data, null, 2), 'utf8');
  await fs.rename(tempPath, filePath);
}

/**
 * Initialize JSON mode storage
 * @param {Object} config - Configuration with file paths
 */
async function initJsonMode(config) {
  if (!USE_JSON_MODE) {
    return;
  }
  
  console.log('📁 Running in JSON compatibility mode');
  
  // Load existing JSON data
  if (config.usersFile) {
    jsonUsers = await loadJsonFile(config.usersFile, []);
    console.log(`  Loaded ${jsonUsers.length} users from JSON`);
  }
  
  if (config.sessionsFile) {
    const sessions = await loadJsonFile(config.sessionsFile, {});
    jsonSessions = new Map(Object.entries(sessions));
    console.log(`  Loaded ${jsonSessions.size} sessions from JSON`);
  }
  
  if (config.affiliatesFile) {
    jsonAffiliates = await loadJsonFile(config.affiliatesFile, []);
    console.log(`  Loaded ${jsonAffiliates.length} affiliates from JSON`);
  }
}

/**
 * Get JSON users (for compatibility)
 * @returns {Array}
 */
function getJsonUsers() {
  return jsonUsers;
}

/**
 * Set JSON users (for compatibility)
 * @param {Array} users
 */
function setJsonUsers(users) {
  jsonUsers = users;
}

/**
 * Get JSON sessions (for compatibility)
 * @returns {Map}
 */
function getJsonSessions() {
  return jsonSessions;
}

/**
 * Get JSON affiliates (for compatibility)
 * @returns {Array}
 */
function getJsonAffiliates() {
  return jsonAffiliates;
}

/**
 * Set JSON affiliates (for compatibility)
 * @param {Array} affiliates
 */
function setJsonAffiliates(affiliates) {
  jsonAffiliates = affiliates;
}

/**
 * Persist JSON users
 * @param {string} filePath
 */
async function persistJsonUsers(filePath) {
  if (!USE_JSON_MODE) {
    return;
  }
  await saveJsonFile(filePath, jsonUsers);
}

/**
 * Persist JSON sessions
 * @param {string} filePath
 */
async function persistJsonSessions(filePath) {
  if (!USE_JSON_MODE) {
    return;
  }
  const sessions = {};
  const now = Date.now();
  for (const [token, session] of jsonSessions.entries()) {
    if (!session.expiresAt || session.expiresAt > now) {
      sessions[token] = session;
    }
  }
  await saveJsonFile(filePath, sessions);
}

/**
 * Persist JSON affiliates
 * @param {string} filePath
 */
async function persistJsonAffiliates(filePath) {
  if (!USE_JSON_MODE) {
    return;
  }
  await saveJsonFile(filePath, jsonAffiliates);
}

module.exports = {
  isJsonMode,
  isDatabaseMode,
  getStorageMode,
  initJsonMode,
  getJsonUsers,
  setJsonUsers,
  getJsonSessions,
  getJsonAffiliates,
  setJsonAffiliates,
  persistJsonUsers,
  persistJsonSessions,
  persistJsonAffiliates,
  loadJsonFile,
  saveJsonFile
};
