import type { Database, ViralAlert } from '@insta-monitor/db';
import type { ViralConfig } from '@insta-monitor/core';

/** Sends one notification message; throws on transport failure. */
export type AlertSender = (text: string) => Promise<void>;

const n = (x: number): string => x.toLocaleString('en-US');

/** One 떡상 reel → a standalone message (link tappable straight to the reel). */
export function formatAlert(a: ViralAlert): string {
  const stats = [a.viewCount != null ? `조회수 ${n(a.viewCount)}` : null, `댓글 ${n(a.commentCount)}`]
    .filter(Boolean)
    .join(' · ');
  return `🔥 떡상 감지\n@${a.username}\n${stats}\n${a.url}`;
}

/** Many 떡상 reels from one collect → a single digest message. */
export function formatDigest(alerts: ViralAlert[]): string {
  const lines = alerts.map((a, i) => {
    const headline = a.viewCount != null ? `${n(a.viewCount)}회` : `${n(a.commentCount)}댓글`;
    return `${i + 1}. @${a.username} · ${headline} · ${a.url}`;
  });
  return `🔥 떡상 ${alerts.length}건\n${lines.join('\n')}`;
}

/**
 * Find newly-viral reels and push them via `send`. Individual messages by default;
 * collapses to one digest when the count exceeds `digestOver`. Marks each reel
 * notified only after its send succeeds, so a transport failure is retried next pass.
 * Never throws — a send error is logged and the unsent reels stay pending.
 * Returns the number of reels actually notified.
 */
export async function notifyNewlyViral(
  db: Database,
  cfg: ViralConfig,
  nowIso: string,
  send: AlertSender,
  opts: { digestOver: number },
): Promise<number> {
  const alerts = db.posts.listNewlyViral(cfg, nowIso);
  if (alerts.length === 0) return 0;

  const sent: number[] = [];
  try {
    if (alerts.length > opts.digestOver) {
      await send(formatDigest(alerts));
      sent.push(...alerts.map((a) => a.id));
    } else {
      for (const a of alerts) {
        await send(formatAlert(a));
        sent.push(a.id);
      }
    }
  } catch (err) {
    console.error('[notify] telegram send failed:', err);
  } finally {
    if (sent.length) db.posts.markNotified(sent, nowIso);
  }
  return sent.length;
}

/**
 * Mark every currently-viral reel as notified WITHOUT sending — call this when the
 * user first configures notifications so the backlog of already-viral reels doesn't
 * flood them; only reels that go viral afterward will alert. Returns how many were
 * suppressed.
 */
export function baselineNotified(db: Database, cfg: ViralConfig, nowIso: string): number {
  const alerts = db.posts.listNewlyViral(cfg, nowIso);
  db.posts.markNotified(alerts.map((a) => a.id), nowIso);
  return alerts.length;
}
