import { drizzle } from "drizzle-orm/postgres-js";
import postgres from "postgres";
import * as schema from "~/database/schema";
import { eq, or } from "drizzle-orm";
import { createDailySnapshot } from "~/models/standings";
import { logger } from "./logger";

// Create a dedicated database connection for the snapshot system
const connectionString = process.env.DATABASE_URL;
if (!connectionString) {
  throw new Error("DATABASE_URL is required for snapshot system");
}
const client = postgres(connectionString);
const db = drizzle(client, { schema });

let snapshotInterval: NodeJS.Timeout | null = null;
const CHECK_INTERVAL = 24 * 60 * 60 * 1000; // Check once per day (in milliseconds)

/**
 * Start the daily snapshot system
 * Runs once per day to create snapshots for all active seasons
 */
export function startSnapshotSystem(): void {
  if (snapshotInterval) {
    logger.log("[Snapshots] Snapshot system already running");
    return;
  }

  // Run immediately on startup
  void createDailySnapshots();

  // Then run once per day
  snapshotInterval = setInterval(async () => {
    try {
      await createDailySnapshots();
    } catch (error) {
      logger.error("[Snapshots] Error creating daily snapshots:", error);
    }
  }, CHECK_INTERVAL);

  logger.log("[Snapshots] Daily snapshot system started (runs once per day)");
}

/**
 * Stop the snapshot system
 */
export function stopSnapshotSystem(): void {
  if (snapshotInterval) {
    clearInterval(snapshotInterval);
    snapshotInterval = null;
    logger.log("[Snapshots] Snapshot system stopped");
  }
}

/**
 * Create daily snapshots for all active seasons
 * Only creates snapshots if they don't already exist for today
 */
async function createDailySnapshots(): Promise<void> {
  const now = new Date();
  const today = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}-${String(now.getDate()).padStart(2, "0")}`;

  logger.log(`[Snapshots] Checking for snapshots to create (${today})`);

  // Get all seasons that are active or in draft (we want to track standings for these)
  const activeSeasons = await db.query.seasons.findMany({
    where: or(
      eq(schema.seasons.status, "active"),
      eq(schema.seasons.status, "draft")
    ),
  });

  if (activeSeasons.length === 0) {
    logger.log("[Snapshots] No active seasons found");
    return;
  }

  logger.log(`[Snapshots] Found ${activeSeasons.length} active season(s)`);

  for (const season of activeSeasons) {
    try {
      await createDailySnapshot(season.id, db);
      logger.log(`[Snapshots] ✅ Upserted snapshot for season ${season.id}`);
    } catch (error) {
      logger.error(`[Snapshots] Error creating snapshot for season ${season.id}:`, error);
    }
  }

  logger.log("[Snapshots] Daily snapshot check complete");
}

/**
 * Manually trigger snapshot creation for specific seasons
 * Useful for admin tools or manual triggers
 */
export async function createSnapshotsForSeasons(seasonIds: string[]): Promise<void> {
  logger.log(`[Snapshots] Manual trigger for ${seasonIds.length} season(s)`);

  for (const seasonId of seasonIds) {
    try {
      await createDailySnapshot(seasonId, db);
      logger.log(`[Snapshots] ✅ Created snapshot for season ${seasonId}`);
    } catch (error) {
      logger.error(`[Snapshots] Error creating snapshot for season ${seasonId}:`, error);
      throw error;
    }
  }
}

/**
 * Manually trigger snapshot creation for all active seasons
 * Useful for testing or manual refreshes
 */
export async function createSnapshotsForAllSeasons(): Promise<void> {
  logger.log("[Snapshots] Manual trigger for all active seasons");
  await createDailySnapshots();
}
