import "server-only";
import { and, eq, isNull, lt, lte } from "drizzle-orm";
import { appDb, schema } from "./appdb";
import { RAPOR_KREDI } from "./credits";
import { krediHatirlatmaEpostasi } from "./eposta";
import { epostaGonder } from "./eposta-gonder";

const { user } = schema;

// 48 saat sonra tek seferlik hatırlatma (PRD İP-A / A2). Env override'ları
// lokal testte akışı dakikalara sıkıştırmak için var.
const GECIKME_MS = Number(
  process.env.KREDI_HATIRLATMA_GECIKME_MS ?? 48 * 60 * 60 * 1000,
);
const ARALIK_MS = Number(
  process.env.KREDI_HATIRLATMA_ARALIK_MS ?? 60 * 60 * 1000,
);

/**
 * Kredisi bitmiş ve 48 saattir dönmemiş kullanıcılara hatırlatma e-postası
 * gönderir. Kredi yüklemek `krediBittiAt`'ı sıfırladığı (grantCredits) ve
 * bakiye filtresi de burada olduğu için yalnızca hâlâ takılı olanlar seçilir.
 * Gönderildi işareti e-postadan ÖNCE koşullu UPDATE ile atılır: yarışta
 * yalnızca bir taraf `rowsAffected === 1` görür — çift gönderim imkânsız,
 * Resend hatasında o kullanıcının hatırlatması yanar (bilinçli at-most-once).
 */
export async function krediHatirlatmaTaramasi(): Promise<void> {
  const esik = new Date(Date.now() - GECIKME_MS);
  const adaylar = await appDb
    .select({ id: user.id, email: user.email })
    .from(user)
    .where(
      and(
        lte(user.krediBittiAt, esik),
        isNull(user.krediHatirlatmaGonderildiAt),
        lt(user.creditBalance, RAPOR_KREDI),
      ),
    )
    .limit(100);

  for (const aday of adaylar) {
    const res = await appDb
      .update(user)
      .set({ krediHatirlatmaGonderildiAt: new Date() })
      .where(
        and(eq(user.id, aday.id), isNull(user.krediHatirlatmaGonderildiAt)),
      );
    if (res.rowsAffected !== 1) continue; // başka instance kazandı

    try {
      await epostaGonder(aday.email, krediHatirlatmaEpostasi());
    } catch (err) {
      console.error(
        `[hatirlatma] Kredi hatırlatması gönderilemedi (${aday.email}):`,
        err,
      );
    }
  }
}

/**
 * Saatlik tarama zamanlayıcısı — instrumentation.ts'ten, sunucu başına bir
 * kez çağrılır. globalThis guard'ı dev hot-reload'da çifte interval'i önler
 * (appdb/index.ts deseni).
 */
export function krediHatirlatmaBaslat(): void {
  const g = globalThis as unknown as { __krediHatirlatmaKuruldu?: boolean };
  if (g.__krediHatirlatmaKuruldu) return;
  g.__krediHatirlatmaKuruldu = true;

  let calisiyor = false;
  const tik = async () => {
    if (calisiyor) return; // önceki tarama uzadıysa üst üste binme
    calisiyor = true;
    try {
      await krediHatirlatmaTaramasi();
    } catch (err) {
      console.error("[hatirlatma] Tarama hatası:", err);
    } finally {
      calisiyor = false;
    }
  };

  // Container yeniden başlarsa saatlik açıklık büyümesin diye kısa bir
  // gecikmeyle açılış taraması da yapılır.
  setTimeout(tik, 60_000);
  setInterval(tik, ARALIK_MS);
}