import type { Notification } from './types';
import { renderTitle, renderBody } from './text';

// The APNs payload.
//
// `aps` is Apple's reserved key and controls what the system does; everything beside it is ours and
// arrives in the app untouched. The doorbell rule lives in what we put in each: the alert carries only a
// generic title composed from the category, and the custom keys carry ids the app uses to FETCH the real
// content over the tailnet. Nothing here should ever be readable as the thing itself.

export type ApnsPayload = {
  aps: {
    alert: { title: string; body?: string };
    sound: string;
    /** Drives the red badge. Only meaningful where a count is, so it is set only then. */
    badge?: number;
    /** Lets the app group/replace banners rather than stacking one per event. */
    'thread-id'?: string;
  };
  /** Ours. The app routes on these; they are ids, never content. */
  officer: {
    type: string;
    id?: string | number;
    ok?: boolean;
  };
};

export function buildApnsPayload(n: Notification): ApnsPayload {
  const body = renderBody(n);

  return {
    aps: {
      alert: body ? { title: renderTitle(n), body } : { title: renderTitle(n) },
      sound: 'default',
      ...(typeof n.count === 'number' ? { badge: n.count } : {}),
      // One thread per category: three job notifications collapse instead of filling the shade.
      'thread-id': n.type,
    },
    officer: {
      type: n.type,
      ...(n.id !== undefined ? { id: n.id } : {}),
      ...(n.ok !== undefined ? { ok: n.ok } : {}),
    },
  };
}

/**
 * `apns-collapse-id` — Apple replaces an undelivered notification with the same id rather than queueing
 * both. Right for "3 new emails" superseding "1 new email"; wrong for jobs, where each completion is its
 * own event, so those collapse per id instead of per category.
 */
export function collapseId(n: Notification): string {
  return n.id !== undefined ? `${n.type}-${n.id}` : n.type;
}
