/**
 * Push subscription management.
 *
 * Handles save, revoke, and list operations for Web Push subscriptions.
 * Subscriptions are tied to a user and identified by endpoint URL.
 */

import type { DrizzleClient } from '../db/client.js';
import {
  deletePushSubscriptionByEndpoint,
  listPushSubscriptionsForUser,
  listPushSubscriptionsForVendor,
  revokePushSubscription,
  savePushSubscription,
} from '../db/queries/push-subscriptions.js';

// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------

export interface SaveSubscriptionInput {
  userId: string;
  endpoint: string;
  p256dh: string;
  auth: string;
  userAgent?: string;
}

export interface RemoveSubscriptionInput {
  userId: string;
  endpoint: string;
}

// ---------------------------------------------------------------------------
// Save (insert or update on conflict)
// ---------------------------------------------------------------------------

/**
 * Insert a new push subscription or update the keys if the endpoint already exists.
 * On re-subscription after permission grant, the endpoint may remain the same but
 * keys can rotate - so we upsert on endpoint.
 */
export async function saveSubscription(
  db: DrizzleClient,
  input: SaveSubscriptionInput,
): Promise<void> {
  await savePushSubscription(db, input);
}

// ---------------------------------------------------------------------------
// Remove (soft-delete: set revoked_at)
// ---------------------------------------------------------------------------

/**
 * Mark a subscription as revoked. Does not hard-delete so we retain the
 * audit trail and avoid race conditions with in-flight notifications.
 */
export async function removeSubscription(
  db: DrizzleClient,
  input: RemoveSubscriptionInput,
): Promise<void> {
  await revokePushSubscription(db, input);
}

/**
 * Hard-delete a subscription by endpoint (called when server receives HTTP 410 Gone).
 * The subscription is permanently invalid and should be removed entirely.
 */
export async function deleteSubscriptionByEndpoint(
  db: DrizzleClient,
  endpoint: string,
): Promise<void> {
  await deletePushSubscriptionByEndpoint(db, endpoint);
}

// ---------------------------------------------------------------------------
// List active subscriptions
// ---------------------------------------------------------------------------

/**
 * Returns all active (non-revoked) subscriptions for a user.
 */
export async function listSubscriptionsForUser(db: DrizzleClient, userId: string) {
  return listPushSubscriptionsForUser(db, userId);
}

/**
 * Returns subscriptions belonging to the owner of the given vendor.
 * Used to notify the vendor's owner user about vendor-level events.
 */
export async function listSubscriptionsForVendor(db: DrizzleClient, vendorId: string) {
  return listPushSubscriptionsForVendor(db, vendorId);
}
