import "dotenv/config";
import path from "node:path";

const required = [
  "ADMIN_SESSION_SECRET",
  "MERCHANT_SESSION_SECRET",
  "INTEGRATION_WEBHOOK_SECRET",
  "MQTT_BROKER_URL",
  "MQTT_USERNAME",
  "MQTT_PASSWORD",
  "MQTT_CLIENT_ID",
  "EXPORT_STORAGE_DIR"
];

const insecureDefaults = new Map([
  ["ADMIN_TOKEN", "admin-dev-token"],
  ["MERCHANT_TOKEN", "merchant-dev-token"],
  ["DEVICE_TOKEN", "device-dev-token"],
  ["MERCHANT_PORTAL_PASSWORD", "merchant"],
  ["INTEGRATION_WEBHOOK_SECRET", "dev-callback-secret"],
  ["MQTT_PASSWORD", "change-me"],
  ["ADMIN_SESSION_SECRET", "change-me-long-random-admin-session-secret"],
  ["MERCHANT_SESSION_SECRET", "change-me-long-random-merchant-session-secret"]
]);

const warnings = [];
const errors = [];

for (const name of required) {
  if (!process.env[name]) {
    errors.push(`${name} is required`);
  }
}

const pgVars = ["PGHOST", "PGPORT", "PGUSER", "PGPASSWORD", "PGDATABASE"];
const hasDatabaseUrl = Boolean(process.env.DATABASE_URL);
const missingPgVars = pgVars.filter((name) => !process.env[name]);
if (!hasDatabaseUrl && missingPgVars.length) {
  errors.push(`DATABASE_URL or ${pgVars.join("/")} is required`);
}

for (const [name, value] of insecureDefaults.entries()) {
  if (name === "ADMIN_TOKEN" && process.env.ADMIN_AUTH_ALLOW_LEGACY_TOKEN === "false") {
    continue;
  }
  if (name === "DEVICE_TOKEN" && process.env.DEVICE_AUTH_ALLOW_LEGACY_TOKEN === "false") {
    continue;
  }
  if (name === "MERCHANT_TOKEN" && process.env.MERCHANT_AUTH_ALLOW_LEGACY_TOKEN === "false") {
    continue;
  }
  if (name === "MERCHANT_PORTAL_PASSWORD" && process.env.MERCHANT_DEV_LOGIN_ENABLED === "false") {
    continue;
  }
  if (process.env[name] === value) {
    errors.push(`${name} still uses the development default`);
  }
}

function requireFalse(name) {
  if (process.env[name] !== "false") {
    errors.push(`${name} must be false in production`);
  }
}

function requireTrue(name, message) {
  if (process.env[name] !== "true") {
    errors.push(message || `${name} must be true in production`);
  }
}

requireFalse("ADMIN_AUTH_ALLOW_LEGACY_TOKEN");
requireFalse("DEVICE_AUTH_ALLOW_LEGACY_TOKEN");
requireFalse("MERCHANT_AUTH_ALLOW_LEGACY_TOKEN");

if (process.env.ADMIN_DEV_LOGIN_ENABLED !== "false") {
  errors.push("ADMIN_DEV_LOGIN_ENABLED must be false in production");
}

if (process.env.MERCHANT_DEV_LOGIN_ENABLED !== "false") {
  errors.push("MERCHANT_DEV_LOGIN_ENABLED must be false in production");
}

if (process.env.MQTT_PUBLISH_MODE !== "broker") {
  errors.push("MQTT_PUBLISH_MODE must be broker in production");
}

if (process.env.MQTT_SUBSCRIBE_ENABLED !== "true") {
  warnings.push("MQTT_SUBSCRIBE_ENABLED should be true when device uplink observability is required");
}

requireTrue("SETTLEMENT_ADJUSTMENT_REQUIRE_APPROVAL", "SETTLEMENT_ADJUSTMENT_REQUIRE_APPROVAL must be true for production finance control");

if (process.env.DATABASE_URL && !/^postgres(ql)?:\/\//.test(process.env.DATABASE_URL)) {
  errors.push("DATABASE_URL must be a postgres connection string");
}

if (!process.env.DATABASE_URL && process.env.PGPORT && !Number.isInteger(Number(process.env.PGPORT))) {
  errors.push("PGPORT must be a number");
}

if (process.env.MQTT_BROKER_URL && !/^mqtts:\/\//.test(process.env.MQTT_BROKER_URL)) {
  warnings.push("MQTT_BROKER_URL should use mqtts:// for production");
}

for (const name of ["ADMIN_SESSION_SECRET", "MERCHANT_SESSION_SECRET", "INTEGRATION_WEBHOOK_SECRET", "MQTT_PASSWORD"]) {
  if ((process.env[name] || "").length < 24) {
    errors.push(`${name} must be at least 24 characters`);
  }
}

if (process.env.LOG_FORMAT !== "json") {
  warnings.push("LOG_FORMAT should be json in production");
}

if (process.env.EXPORT_WORKER_ENABLED !== "true") {
  errors.push("EXPORT_WORKER_ENABLED must be true in production");
}

if (Number(process.env.EXPORT_RETENTION_DAYS || 0) <= 0) {
  errors.push("EXPORT_RETENTION_DAYS must be a positive number");
}

if (process.env.EXPORT_STORAGE_DIR && !path.isAbsolute(process.env.EXPORT_STORAGE_DIR)) {
  errors.push("EXPORT_STORAGE_DIR must be an absolute path in production");
}

if (process.env.RATE_LIMIT_ENABLED !== "true") {
  errors.push("RATE_LIMIT_ENABLED must be true in production");
}

if (process.env.TRUST_PROXY !== "true") {
  warnings.push("TRUST_PROXY should be true when running behind a reverse proxy/load balancer");
}

if (!process.env.JSON_BODY_LIMIT) {
  errors.push("JSON_BODY_LIMIT is required");
}

for (const warning of warnings) {
  console.warn(`WARN ${warning}`);
}

if (errors.length) {
  for (const error of errors) {
    console.error(`ERROR ${error}`);
  }
  process.exit(1);
}

console.log("Production environment preflight passed");
