/**
 * Notification REST API — mounted at /api/notifications
 *
 * All endpoints require Bearer auth (same pattern as spaces.ts).
 */

import { Hono } from "hono";
import {
  verifyEncryptIDToken,
  extractToken,
} from "@encryptid/sdk/server";
import {
  getUserNotifications,
  getUnreadCount,
  markNotificationRead,
  markAllNotificationsRead,
  dismissNotification,
  getNotificationPreferences,
  upsertNotificationPreferences,
} from "../src/encryptid/db";

export const notificationRouter = new Hono();

// ── Auth helper ──
async function requireAuth(req: Request) {
  const token = extractToken(req.headers);
  if (!token) return null;
  try {
    return await verifyEncryptIDToken(token);
  } catch {
    return null;
  }
}

// ── GET / — Paginated notification list ──
notificationRouter.get("/", async (c) => {
  const claims = await requireAuth(c.req.raw);
  if (!claims) return c.json({ error: "Authentication required" }, 401);

  const url = new URL(c.req.url);
  const unreadOnly = url.searchParams.get("unread") === "true";
  const category = url.searchParams.get("category") || undefined;
  const limit = Math.min(Number(url.searchParams.get("limit")) || 50, 100);
  const offset = Number(url.searchParams.get("offset")) || 0;

  const notifications = await getUserNotifications(claims.sub, {
    unreadOnly,
    category,
    limit,
    offset,
  });

  return c.json({ notifications });
});

// ── GET /count — Lightweight unread count (polling fallback) ──
notificationRouter.get("/count", async (c) => {
  const claims = await requireAuth(c.req.raw);
  if (!claims) return c.json({ error: "Authentication required" }, 401);

  const count = await getUnreadCount(claims.sub);
  return c.json({ unreadCount: count });
});

// ── PATCH /:id/read — Mark one notification as read ──
notificationRouter.patch("/:id/read", async (c) => {
  const claims = await requireAuth(c.req.raw);
  if (!claims) return c.json({ error: "Authentication required" }, 401);

  const id = c.req.param("id");
  const ok = await markNotificationRead(id, claims.sub);
  if (!ok) return c.json({ error: "Notification not found" }, 404);
  return c.json({ ok: true });
});

// ── POST /read-all — Mark all read (optional scope) ──
notificationRouter.post("/read-all", async (c) => {
  const claims = await requireAuth(c.req.raw);
  if (!claims) return c.json({ error: "Authentication required" }, 401);

  let spaceSlug: string | undefined;
  let category: string | undefined;
  try {
    const body = await c.req.json();
    spaceSlug = body.spaceSlug;
    category = body.category;
  } catch {
    // No body is fine — mark everything read
  }

  const count = await markAllNotificationsRead(claims.sub, { spaceSlug, category });
  return c.json({ ok: true, markedRead: count });
});

// ── DELETE /:id — Dismiss/archive a notification ──
notificationRouter.delete("/:id", async (c) => {
  const claims = await requireAuth(c.req.raw);
  if (!claims) return c.json({ error: "Authentication required" }, 401);

  const id = c.req.param("id");
  const ok = await dismissNotification(id, claims.sub);
  if (!ok) return c.json({ error: "Notification not found" }, 404);
  return c.json({ ok: true });
});

// ── GET /preferences — Get notification preferences ──
notificationRouter.get("/preferences", async (c) => {
  const claims = await requireAuth(c.req.raw);
  if (!claims) return c.json({ error: "Authentication required" }, 401);

  const prefs = await getNotificationPreferences(claims.sub);
  return c.json({ preferences: prefs || {
    emailEnabled: true,
    pushEnabled: true,
    quietHoursStart: null,
    quietHoursEnd: null,
    mutedSpaces: [],
    mutedCategories: [],
    digestFrequency: 'none',
  }});
});

// ── PATCH /preferences — Update notification preferences ──
notificationRouter.patch("/preferences", async (c) => {
  const claims = await requireAuth(c.req.raw);
  if (!claims) return c.json({ error: "Authentication required" }, 401);

  const body = await c.req.json();
  const prefs = await upsertNotificationPreferences(claims.sub, body);
  return c.json({ preferences: prefs });
});
