"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.disconnectDatabase = exports.connectDatabase = void 0;
const mongoose_1 = __importDefault(require("mongoose"));
let listenersRegistered = false;
let reconnectTimer;
const connectDatabase = async (mongoUri, logger) => {
    if (!mongoUri) {
        logger.warn("MONGO_URI is not configured; subscription payments are disabled.");
        return false;
    }
    if (!listenersRegistered) {
        mongoose_1.default.connection.on("error", (error) => {
            logger.error("MongoDB connection error.", {
                message: error instanceof Error ? error.message : String(error)
            });
        });
        mongoose_1.default.connection.on("disconnected", () => {
            logger.warn("MongoDB disconnected; Mongoose will attempt to reconnect automatically.");
        });
        mongoose_1.default.connection.on("reconnected", () => {
            logger.info("MongoDB reconnected.");
        });
        mongoose_1.default.connection.on("reconnectFailed", () => {
            logger.error("MongoDB reconnection failed; the process may need to be restarted.");
        });
        listenersRegistered = true;
    }
    return tryConnect(mongoUri, logger);
};
exports.connectDatabase = connectDatabase;
const tryConnect = async (mongoUri, logger) => {
    try {
        await mongoose_1.default.connect(mongoUri, {
            serverSelectionTimeoutMS: 10_000,
            socketTimeoutMS: 0,
            connectTimeoutMS: 10_000,
            heartbeatFrequencyMS: 10_000,
            maxPoolSize: 10,
            minPoolSize: 2,
            retryWrites: true
        });
        logger.info("Signals subscription database connected.");
        return true;
    }
    catch (error) {
        const message = error instanceof Error ? error.message : String(error);
        logger.error("Database connection failed. Subscription features are disabled until the database is reachable.", {
            error: message,
            hint: "If you use MongoDB Atlas, add this server's IP to Atlas Network Access, or temporarily allow access from anywhere (0.0.0.0/0) to test. Shared hosts often block or throttle outbound MongoDB traffic."
        });
        scheduleReconnect(mongoUri, logger);
        return false;
    }
};
const scheduleReconnect = (mongoUri, logger) => {
    if (reconnectTimer)
        return;
    reconnectTimer = setTimeout(async () => {
        reconnectTimer = undefined;
        logger.info("Retrying database connection...");
        const ok = await tryConnect(mongoUri, logger);
        if (!ok) {
            scheduleReconnect(mongoUri, logger);
        }
        else {
            logger.info("Database is now reachable. Restart the application to fully enable subscription/payment features.");
        }
    }, 30_000);
    reconnectTimer.unref?.();
};
const disconnectDatabase = async () => {
    if (reconnectTimer) {
        clearTimeout(reconnectTimer);
        reconnectTimer = undefined;
    }
    if (mongoose_1.default.connection.readyState !== 0) {
        await mongoose_1.default.disconnect();
    }
};
exports.disconnectDatabase = disconnectDatabase;
