// cron/back-in-stock-sweep.ts — find deals with pending restock watches that
// now have stock, dispatch notifications via checkAndEmitRestockAlerts.

import { createDbService } from '@/server/services/db.js';
import { withSentry } from '@/server/observability/with-sentry';
import type { TxDrizzleClient } from '@/server/db/client.js';
import type { CronEnv } from './deal-expiry.js';
import { invalidateCatalog } from '@/server/cache/invalidate.js';
import { checkAndEmitRestockAlerts } from '@/server/stock/checkRestockAlerts.js';
import { sql } from 'drizzle-orm';

export const runBackInStockSweep = withSentry(
  async function runBackInStockSweep(env: CronEnv): Promise<void> {
    const db: TxDrizzleClient = createDbService({ DATABASE_URL: env.DATABASE_URL });

    // Find distinct deal IDs that have pending watches whose item now has stock.
    const result = (await db.execute(sql`
      SELECT DISTINCT sw.deal_id
      FROM stock_watchlist sw
      JOIN deals d ON d.id = sw.deal_id
      WHERE sw.notified_at IS NULL
        AND sw.expires_at > NOW()
        AND (
          (sw.sku_id IS NULL AND d.stock_remaining > 0)
          OR
          (sw.sku_id IS NOT NULL AND EXISTS (
            SELECT 1 FROM deal_skus ds
            WHERE ds.id = sw.sku_id
              AND ds.quantity_total - ds.quantity_sold > 0
          ))
        )
    `)) as { rows: Array<{ deal_id: string }> };

    let restockedCount = 0;
    for (const row of result.rows) {
      const dealId = row.deal_id;
      const restocked = await checkAndEmitRestockAlerts(db, env, dealId);
      if (restocked) restockedCount++;
    }
    if (restockedCount > 0) {
      await invalidateCatalog(db, { scope: 'global' });
    }
  },
  { name: 'cron.back-in-stock-sweep', kind: 'cron' },
);
