import { readFileSync } from 'node:fs';
import { dirname, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
import { parseProxyUrl } from './proxy.js';

const projectRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..');

/**
 * Loads `.env` into process.env without a dependency. Node's own `--env-file` needs 20.6+;
 * parsing it here keeps the runbook a plain `npm start` on any Node 18+.
 * Real environment variables always win, so a container/CI can override the file.
 */
function loadDotEnv() {
  let raw;
  try {
    raw = readFileSync(resolve(projectRoot, '.env'), 'utf8');
  } catch {
    return;
  }

  for (const line of raw.split(/\r?\n/)) {
    const trimmed = line.trim();
    if (!trimmed || trimmed.startsWith('#')) continue;

    const eq = trimmed.indexOf('=');
    if (eq === -1) continue;

    const key = trimmed.slice(0, eq).trim();
    let value = trimmed.slice(eq + 1).trim();
    if (value.length >= 2 && ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'")))) {
      value = value.slice(1, -1);
    }

    if (!(key in process.env)) process.env[key] = value;
  }
}

loadDotEnv();

const botToken = (process.env.TELEGRAM_BOT_TOKEN ?? '').trim();
if (!botToken) {
  console.error('FATAL: TELEGRAM_BOT_TOKEN is not set. Copy .env.example to .env and paste the token from @BotFather.');
  process.exit(1);
}

const chatIds = (process.env.TELEGRAM_CHAT_IDS ?? '')
  .split(',')
  .map((id) => id.trim())
  .filter(Boolean);

// The API key is mandatory, with no opt-out: an OTP relay that anyone can POST to is an open
// message cannon pointed at the test group's phones. Fail to start rather than listen unprotected.
const apiKey = (process.env.API_KEY ?? '').trim();
if (!apiKey) {
  console.error('FATAL: API_KEY is not set. Choose any shared secret, put it in .env, and configure the same value on the caller.');
  process.exit(1);
}

if (apiKey.length < 16) {
  console.error(`FATAL: API_KEY is too short (${apiKey.length} chars). Use at least 16 — e.g. output of: node -e "console.log(require('crypto').randomBytes(24).toString('hex'))"`);
  process.exit(1);
}

// Opt-in outbound proxy for this process's own hop to api.telegram.org (filtered in Iran). Absent ⇒ direct,
// exactly as before. TELEGRAM_PROXY_URL wins so the relay can be proxied without proxying anything else on the
// box; the standard variables are honoured as a fallback because that is where a container already puts it.
const proxyUrl = (
  process.env.TELEGRAM_PROXY_URL ??
  process.env.HTTPS_PROXY ?? process.env.https_proxy ??
  process.env.ALL_PROXY ?? process.env.all_proxy ??
  ''
).trim();

let proxy = null;
if (proxyUrl) {
  try {
    proxy = parseProxyUrl(proxyUrl);
  } catch (error) {
    // Fail at boot: a misspelled proxy would otherwise surface as an unexplained delivery failure per OTP.
    console.error(`FATAL: ${error.message}`);
    process.exit(1);
  }
}

export const config = {
  botToken,
  chatIds,
  apiKey,
  proxy,
  host: (process.env.HOST ?? '127.0.0.1').trim(),
  port: Number(process.env.PORT ?? 5010),
  redactCodeInLogs: (process.env.REDACT_CODE_IN_LOGS ?? 'false').toLowerCase() === 'true',
};
