import dns from "dns";
import "../config/env";
import mongoose from "mongoose";

const MONGODB_CONNECTION = process.env.MONGODB_CONNECTION;

// Some local DNS servers refuse SRV lookups needed by mongodb+srv:// URIs
if (MONGODB_CONNECTION?.startsWith("mongodb+srv://")) {
  dns.setServers(["8.8.8.8", "1.1.1.1"]);
}

// Surface connection-pool drops (e.g. a TLS handshake reset from Atlas)
// instead of letting queries silently buffer until Mongoose's default
// 10s buffering timeout kicks in with no indication of why.
mongoose.connection.on("connected", () => {
  console.log("[MongoDB] connected");
});
mongoose.connection.on("error", (err) => {
  console.error("[MongoDB] connection error:", err.message);
});
mongoose.connection.on("disconnected", () => {
  console.warn("[MongoDB] disconnected — mongoose will attempt to reconnect");
});
mongoose.connection.on("reconnected", () => {
  console.log("[MongoDB] reconnected");
});

const CONNECT_OPTIONS = {
  serverSelectionTimeoutMS: 15000,
  socketTimeoutMS: 45000,
  // Proactively recycle idle pooled connections before a NAT/firewall
  // between the server and Atlas can silently kill them. Reusing a
  // connection that's dead-but-not-yet-detected is what produces the
  // "tlsv1 alert internal error" / ResetPool failure — this keeps the
  // pool from ever holding a connection that idle long.
  maxIdleTimeMS: 60000,
  autoIndex: true,
};

const RETRY_DELAY_MS = 5000;

export async function databaseConnect(): Promise<void> {
  if (!MONGODB_CONNECTION) return;

  try {
    await mongoose.connect(MONGODB_CONNECTION, CONNECT_OPTIONS);
  } catch (err: any) {
    console.error(
      `[MongoDB] initial connection failed (${err.message}); retrying in ${RETRY_DELAY_MS}ms`,
    );
    await new Promise((resolve) => setTimeout(resolve, RETRY_DELAY_MS));
    return databaseConnect();
  }
}

export async function databaseDisconnect() {
  await mongoose.disconnect();
}
