'use strict';

const fs = require('fs');
const path = require('path');
const yaml = require('js-yaml');

const DEFAULT_CONFIG = {
  server: { port: 6070, host: '0.0.0.0' },
  bots: {
    max_bots: 500,
    default_rate: 1,
    default_spawn_delay: 200,
    max_spawn_delay: 5000,
    max_packet_rate: 100,
    password: 'password123',
    join_delay_ms: 500,
    chat_messages: [],
    auth_phrases: {
      register_success: ['successfully registered'],
      already_registered: ['already registered', 'already logged'],
      login_success: ['you have been logged', 'welcome back', 'successfully logged'],
    },
    auth_timeout_ms: 2500,
  },
  proxy: {
    test_timeout_ms: 10000,
    concurrency: 16,
    max_list_size: 5000,
    probe_host: '8.8.8.8',
    probe_port: 53,
    score_decay_ms: 60000,
    score_penalty_per_fail: 10,
    score_recovery_after_ms: 300000,
    alive_latency_max_ms: 2000,
    per_proxy_inflight_cap: 5,
    default_strategy: 'best-score',
  },
  logging: { max_log_entries: 2000, max_dom_logs: 500, daily_log_dir: 'logs' },
  auth: { session_hours: 24 },
  rate_limits: {
    login_per_15min: 5,
    proxy_upload_per_hour: 10,
    test_start_per_min: 10,
    broadcast_chat_per_min: 30,
  },
  cors: { origins: [] },
  quick_commands: ['/kill', '/spawn', '/tpaccept'],
};

function deepMerge(target, source) {
  if (!source || typeof source !== 'object') return target;
  for (const [k, v] of Object.entries(source)) {
    if (v && typeof v === 'object' && !Array.isArray(v) && target[k] && typeof target[k] === 'object' && !Array.isArray(target[k])) {
      deepMerge(target[k], v);
    } else {
      target[k] = v;
    }
  }
  return target;
}

function loadConfig(configPath) {
  let userCfg = {};
  try {
    if (fs.existsSync(configPath)) {
      userCfg = yaml.load(fs.readFileSync(configPath, 'utf8')) || {};
    }
  } catch (err) {
    console.error(`[config] Failed to parse ${configPath}: ${err.message}`);
  }
  const merged = deepMerge(JSON.parse(JSON.stringify(DEFAULT_CONFIG)), userCfg);
  merged.server.port = parseInt(process.env.PORT, 10) || merged.server.port;
  merged.server.host = process.env.HOST || merged.server.host;
  return Object.freeze(merged);
}

function getSecret(name, fallback) {
  return process.env[name] || fallback;
}

function validateSecrets() {
  const errors = [];
  if (!process.env.SITE_PASSWORD) {
    errors.push('SITE_PASSWORD is not set in .env');
  }
  const secret = process.env.SESSION_SECRET;
  if (!secret || secret === 'default_secret') {
    errors.push('SESSION_SECRET is not set or is using the default value. Set a strong random value in .env');
  }
  return errors;
}

module.exports = { loadConfig, getSecret, validateSecrets, DEFAULT_CONFIG };
