import { query } from '../db.js';

export interface PushMessage {
  title: string;
  body: string;
  data?: Record<string, string | number | boolean | null>;
  sound?: 'default' | null;
  channelId?: string;
}

interface ExpoPushTicket {
  status: 'ok' | 'error';
  id?: string;
  message?: string;
  details?: { error?: string };
}

function isExpoPushToken(token: string): boolean {
  return /^(ExponentPushToken|ExpoPushToken)\[[A-Za-z0-9_-]+\]$/.test(token);
}

export async function sendPushToUsers(userIds: string[], message: PushMessage) {
  const uniqueUserIds = [...new Set(userIds.filter(Boolean))];
  if (!uniqueUserIds.length) return { requested: 0, sent: 0, failed: 0 };

  const { rows } = await query<{ token: string }>(
    `SELECT token FROM device_push_tokens
     WHERE user_id = ANY($1::uuid[]) AND is_active=true`,
    [uniqueUserIds]
  );
  const tokens = [...new Set(rows.map(row => row.token).filter(isExpoPushToken))];
  if (!tokens.length) return { requested: 0, sent: 0, failed: 0 };

  const payload = tokens.map(to => ({
    to,
    title: message.title,
    body: message.body,
    sound: message.sound ?? 'default',
    channelId: message.channelId ?? 'service-updates',
    data: message.data ?? {},
    priority: 'high',
  }));

  try {
    const response = await fetch('https://exp.host/--/api/v2/push/send', {
      method: 'POST',
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(payload),
    });
    const result = await response.json() as { data?: ExpoPushTicket[] };
    if (!response.ok) throw new Error(`Push gateway rejected request (${response.status}).`);
    const tickets = result.data ?? [];
    const sent = tickets.filter(ticket => ticket.status === 'ok').length;
    const failed = Math.max(0, tokens.length - sent);
    return { requested: tokens.length, sent, failed };
  } catch (error) {
    console.error('Push delivery failed:', error);
    return { requested: tokens.length, sent: 0, failed: tokens.length };
  }
}
