import type { Database } from 'bun:sqlite';
import { normalizeWhatsAppId } from '../../utils/whatsapp';
import { ResponseQueue } from '../response-queue';
import { Metrics } from '../metrics';

/**
 * Revoke calendar tokens and deactivate memberships for groups that have
 * been deactivated (no longer present in the API snapshot).
 */
export function revokeTokensAndDeactivateMembers(
  db: Database,
  deactivatedIds: string[],
  txn: (fn: () => void) => void = fn => fn()
): void {
  if (deactivatedIds.length === 0) return;
  txn(() => {
    for (const groupId of deactivatedIds) {
      db.prepare(`
        UPDATE calendar_tokens
        SET revoked_at = strftime('%Y-%m-%d %H:%M:%f','now')
        WHERE group_id = ? AND revoked_at IS NULL
      `).run(groupId);
      db.prepare(`
        UPDATE group_members
        SET is_active = 0
        WHERE group_id = ? AND is_active = 1
      `).run(groupId);
    }
  });
}

/**
 * Queue admin notifications about deactivated groups.
 * Skips in test mode.
 */
export async function notifyAdminsAboutDeactivated(
  deactivated: Array<{ id: string; name: string | null }>
): Promise<void> {
  if (deactivated.length === 0) return;
  if (String(process.env.NODE_ENV || '').toLowerCase() === 'test') return;

  const adminSet = new Set<string>();
  const rawAdmins = String(process.env.ADMIN_USERS || '');
  for (const token of rawAdmins.split(',').map(s => s.trim()).filter(Boolean)) {
    const n = normalizeWhatsAppId(token);
    if (n) adminSet.add(n);
  }
  const admins = Array.from(adminSet);
  if (admins.length === 0) return;

  const messages: Array<{ recipient: string; message: string }> = [];
  for (const g of deactivated) {
    const label = g.name ? `${g.name} (${g.id})` : g.id;
    const msg =
      `⚠️ El grupo ${label} parece haber dejado de existir o no está disponible.\n\n` +
      `Acciones disponibles:\n- Archivar (recomendado): /admin archivar-grupo ${g.id}\n` +
      `- Borrar definitivamente: /admin borrar-grupo ${g.id}`;
    for (const admin of admins) {
      messages.push({ recipient: admin, message: msg });
    }
  }

  if (messages.length > 0) {
    try {
      await ResponseQueue.add(messages as any);
      Metrics.inc('admin_deactivation_notifications', messages.length);
    } catch (e) {
      console.warn('No se pudo encolar notificación a admins:', e);
    }
  }
}

/**
 * Full deactivation pipeline: revoke tokens, deactivate members, notify admins.
 */
export async function handleDeactivatedGroups(
  db: Database,
  deactivated: Array<{ id: string; name: string | null }>
): Promise<void> {
  if (deactivated.length === 0) return;

  const ids = deactivated.map(g => g.id);
  revokeTokensAndDeactivateMembers(db, ids, fn => db.transaction(fn)());
  await notifyAdminsAboutDeactivated(deactivated);
}
