import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';

const __dirname = path.dirname(fileURLToPath(import.meta.url));
export const projectRoot = path.resolve(__dirname, '../..');
export const envPath = path.resolve(process.env.ONLYCOIN_ENV_PATH || path.join(projectRoot, '.env'));

export function parseEnv(text = '') {
  const output = {};
  for (const rawLine of String(text).split(/\r?\n/)) {
    const line = rawLine.trim();
    if (!line || line.startsWith('#')) continue;
    const index = line.indexOf('=');
    if (index <= 0) continue;
    const key = line.slice(0, index).trim();
    let value = line.slice(index + 1).trim();
    if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) {
      value = value.slice(1, -1).replace(/\\n/g, '\n').replace(/\\r/g, '\r');
    }
    output[key] = value;
  }
  return output;
}

export function loadProjectEnv({ override = false } = {}) {
  if (!fs.existsSync(envPath)) return {};
  const values = parseEnv(fs.readFileSync(envPath, 'utf8'));
  for (const [key, value] of Object.entries(values)) {
    if (override || process.env[key] == null || process.env[key] === '') process.env[key] = value;
  }
  return values;
}

function quoteEnv(value) {
  const text = String(value ?? '');
  if (/^[A-Za-z0-9_./:@+-]*$/.test(text)) return text;
  return `"${text.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\r/g, '\\r').replace(/\n/g, '\\n')}"`;
}

export function writeProjectEnv(values, { comments = true } = {}) {
  const ordered = [
    'APP_VERSION', 'NODE_ENV', 'HOST', 'PORT', 'APP_ORIGIN', 'DATA_DIR', 'TRUST_PROXY',
    'AUTH_SECRET', 'INSTALLATION_ID', 'TELEGRAM_BOT_TOKEN', 'TELEGRAM_WEBHOOK_SECRET',
    'PUBLIC_URL', 'EVM_RPC_URL', 'BITCOIN_RPC_URL', 'BITCOIN_RPC_USER', 'BITCOIN_RPC_PASSWORD'
  ];
  const keys = [...ordered.filter((key) => Object.hasOwn(values, key)), ...Object.keys(values).filter((key) => !ordered.includes(key)).sort()];
  const lines = [];
  if (comments) {
    lines.push('# OnlyCoin production runtime configuration.');
    lines.push('# Keep this file outside public web roots and restrict filesystem permissions.');
    lines.push('# Private keys and seed phrases must never be stored here.');
    lines.push('');
  }
  for (const key of keys) lines.push(`${key}=${quoteEnv(values[key])}`);
  lines.push('');
  const temporary = `${envPath}.${process.pid}.${Date.now()}.tmp`;
  fs.writeFileSync(temporary, lines.join('\n'), { encoding: 'utf8', mode: 0o600 });
  fs.renameSync(temporary, envPath);
  try { fs.chmodSync(envPath, 0o600); } catch { /* Windows ACLs are managed by the host. */ }
  return envPath;
}

loadProjectEnv();
