import fs from 'node:fs';
import crypto from 'node:crypto';
import { SELF_HOST_GENERATED_ENV_VARS } from '../app/lib/setup/runtime-env-prerequisites.mjs';

function parseArgs(argv) {
  const args = {};
  for (let i = 0; i < argv.length; i++) {
    const a = argv[i];
    if (a === '--database-url') args.databaseUrl = argv[++i];
    if (a === '--nextauth-url') args.nextauthUrl = argv[++i];
  }
  return args;
}

function parseEnvFile(text) {
  const env = {};
  const lines = text.split(/\r?\n/);
  for (const line of lines) {
    const trimmed = line.trim();
    if (!trimmed || trimmed.startsWith('#')) continue;
    const idx = trimmed.indexOf('=');
    if (idx === -1) continue;
    const k = trimmed.slice(0, idx).trim();
    const v = trimmed.slice(idx + 1).trim();
    env[k] = v;
  }
  return env;
}

function base64url(bytes) {
  return bytes.toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/g, '');
}

function ensure(env, key, valueFn) {
  if (env[key]) return;
  env[key] = valueFn();
}

function formatEnv(env, keep) {
  const header = `# Generated by scripts/init-self-host-env.mjs on ${new Date().toISOString()}\n`;

  const preferredOrder = SELF_HOST_GENERATED_ENV_VARS;

  const lines = [];
  for (const k of preferredOrder) {
    if (env[k] != null) lines.push(`${k}=${env[k]}`);
  }

  const extras = Object.keys(env)
    .filter(k => !preferredOrder.includes(k))
    .sort((a, b) => a.localeCompare(b))
    .map(k => `${k}=${env[k]}`);

  return header + lines.join('\n') + (extras.length ? `\n\n# Existing / extra values\n${extras.join('\n')}\n` : '\n');
}

const args = parseArgs(process.argv.slice(2));

const envPath = '.env.local';
const existingText = fs.existsSync(envPath) ? fs.readFileSync(envPath, 'utf8') : '';
const env = existingText ? parseEnvFile(existingText) : {};

// Required
const dbUrl = args.databaseUrl || process.env.DATABASE_URL || env.DATABASE_URL;
if (!dbUrl) {
  console.error('[init-self-host-env] Missing DATABASE_URL. Provide --database-url or set DATABASE_URL in the environment.');
  process.exit(1);
}
env.DATABASE_URL = dbUrl;

// Modes
ensure(env, 'DASHCLAW_MODE', () => 'self_host');
ensure(env, 'NEXT_PUBLIC_DASHCLAW_MODE', () => env.DASHCLAW_MODE);

// NextAuth defaults for local self-host (can be overridden by args or existing values)
if (args.nextauthUrl) env.NEXTAUTH_URL = args.nextauthUrl;
ensure(env, 'NEXTAUTH_URL', () => 'http://localhost:3000');
ensure(env, 'NEXTAUTH_SECRET', () => base64url(crypto.randomBytes(32)));

// API & encryption
ensure(env, 'DASHCLAW_API_KEY', () => `oc_live_${crypto.randomBytes(24).toString('hex')}`);
ensure(env, 'ENCRYPTION_KEY', () => base64url(crypto.randomBytes(32)).slice(0, 32));

fs.writeFileSync(envPath, formatEnv(env), 'utf8');

console.log('[init-self-host-env] Wrote .env.local');
console.log('');
console.log('Dashboard URL: ' + (env.NEXTAUTH_URL || 'http://localhost:3000'));
const redactedApiKey = env.DASHCLAW_API_KEY ? env.DASHCLAW_API_KEY.replace(/.(?=.{4})/g, '*') : '(not set)';
console.log('Admin API key (redacted): ' + redactedApiKey);
console.log('Full value stored in .env.local as DASHCLAW_API_KEY.');
console.log('');
console.log('Agent env snippet (fill in DASHCLAW_API_KEY from .env.local):');
console.log('DASHCLAW_BASE_URL=' + (env.NEXTAUTH_URL || 'http://localhost:3000'));
console.log('DASHCLAW_API_KEY=${DASHCLAW_API_KEY}');
