/**
 * Push notification API routes.
 *
 * Provides endpoints for managing Web Push subscriptions
 * and retrieving the VAPID public key for client-side subscription.
 */

import type { Hono } from "hono";
import { z } from "zod";
import {
  getVapidPublicKey,
  addSubscription,
  removeSubscription,
  getSubscriptionCount,
  sendTestNotification,
} from "../push-notifications.js";
import { parseBody } from "../validation.js";
import { createLogger } from "../logger.js";

const log = createLogger("push-routes");

// ─── Zod Schemas ──────────────────────────────────────────────────

const subscribeSchema = z.object({
  endpoint: z.string().url().max(2000),
  keys: z.object({
    p256dh: z.string().min(1).max(500),
    auth: z.string().min(1).max(500),
  }),
});

const unsubscribeSchema = z.object({
  endpoint: z.string().url().max(2000),
});

// ─── Route Registration ───────────────────────────────────────────

export function registerPushRoutes(api: Hono): void {
  // Get VAPID public key for client-side push subscription
  api.get("/push/vapid-key", async (c) => {
    try {
      const publicKey = await getVapidPublicKey();
      return c.json({ publicKey });
    } catch (err) {
      log.error({ err }, "Failed to get VAPID public key");
      return c.json({ error: "Failed to get VAPID key" }, 500);
    }
  });

  // Subscribe to push notifications
  api.post("/push/subscribe", async (c) => {
    const body = await parseBody(c, subscribeSchema);
    if (!body.success) return body.response;

    addSubscription(body.data);
    return c.json({
      ok: true,
      subscriptionCount: getSubscriptionCount(),
    });
  });

  // Unsubscribe from push notifications
  api.post("/push/unsubscribe", async (c) => {
    const body = await parseBody(c, unsubscribeSchema);
    if (!body.success) return body.response;

    const removed = removeSubscription(body.data.endpoint);
    return c.json({
      ok: true,
      removed,
      subscriptionCount: getSubscriptionCount(),
    });
  });

  // Get subscription status
  api.get("/push/status", (c) => {
    return c.json({
      subscriptionCount: getSubscriptionCount(),
    });
  });

  // Send a test notification
  api.post("/push/test", async (c) => {
    try {
      const sent = await sendTestNotification();
      return c.json({ ok: true, sent });
    } catch (err) {
      log.error({ err }, "Failed to send test notification");
      return c.json({ error: "Failed to send test notification" }, 500);
    }
  });
}
