/**
 * Run Full Historical Feeder
 * Usage: npm run feeder:historical
 *
 * Includes a watchdog that kills the process if no activity
 * is detected for 5 minutes (stuck API request), letting PM2
 * auto-restart and resume from DB.
 */

import { NestFactory } from "@nestjs/core";
import { FeederService } from "../modules/feeder/feeder.service";
import { Logger } from "@nestjs/common";

const WATCHDOG_INTERVAL_MS = 60_000; // Check every 1 minute
const WATCHDOG_TIMEOUT_MS = 3 * 60_000; // Kill if no activity for 3 minutes

async function bootstrap() {
  process.env.FEEDER_MODE = "historical";

  const logger = new Logger("FeederScript");

  logger.log("🚀 Starting full historical feeder...");

  // Load AppModule after FEEDER_MODE is set so cron imports can be disabled.
  // eslint-disable-next-line @typescript-eslint/no-require-imports
  const { AppModule } = require("../app.module");
  const app = await NestFactory.createApplicationContext(AppModule, {
    logger: ["log", "error", "warn"],
  });

  const feederService = app.get(FeederService);

  // ── Watchdog Timer ──────────────────────────────────────────
  // If the feeder hangs on an API call for 3+ minutes, force-kill
  // so PM2 can restart and resume from where it left off in DB.
  // NOTE: process.exit(1) alone can be blocked by open handles
  // (DB connections, HTTP sockets). We use process.kill(SIGKILL)
  // as an unconditional fallback.
  const watchdog = setInterval(() => {
    const idleMs = Date.now() - feederService.lastActivityAt;
    if (idleMs > WATCHDOG_TIMEOUT_MS) {
      logger.error(
        `🐕 WATCHDOG: No activity for ${Math.round(idleMs / 1000)}s. Force-killing for PM2 restart...`,
      );

      // Try graceful exit first
      try {
        process.exit(1);
      } catch {
        // Ignored – fallback below
      }

      // If process.exit didn't work (blocked by open handles),
      // schedule an unconditional SIGKILL after 2 seconds
      setTimeout(() => {
        logger.error("🐕 WATCHDOG: process.exit blocked. Sending SIGKILL...");
        process.kill(process.pid, "SIGKILL");
      }, 2_000).unref();
    }
  }, WATCHDOG_INTERVAL_MS);

  // Don't let the watchdog timer keep the process alive after scan finishes
  watchdog.unref();

  try {
    const startDate = process.env.FEEDER_START_DATE || "2023-06-01";
    const sports = (process.env.FEEDER_SPORTS || "football,basketball")
      .split(",")
      .map((sport) => sport.trim())
      .filter(Boolean) as Array<"football" | "basketball">;

    await feederService.runHistoricalScan(sports, startDate);
    logger.log("✅ Full historical feeder completed successfully!");
  } catch (error: any) {
    logger.error(`❌ Feeder failed: ${error.message}`);
    logger.error(error.stack);
    process.exit(1);
  } finally {
    clearInterval(watchdog);
    await app.close();
  }

  process.exit(0);
}

void bootstrap();
