/**
 * Notifications REST endpoints.
 *
 * POST   /devices              — register/update device
 * GET    /devices/:userId      — list user devices
 * DELETE /devices/:id          — remove device
 * GET    /notifications/prefs/:userId  — get notification preferences
 * PUT    /notifications/prefs/:userId  — update notification preferences
 */

import type { FastifyInstance } from 'fastify';
import { getRequestProductId } from '../../lib/request-context.js';
import { BadRequestError, NotFoundError } from '../../lib/errors.js';
import * as repo from './repository.js';
import {
  RegisterDeviceSchema,
  UpdatePrefsSchema,
  type DeviceDoc,
  type NotificationPrefsDoc,
} from './types.js';

export async function notificationRoutes(app: FastifyInstance) {
  // Register/update device
  app.post('/devices', async req => {
    const parsed = RegisterDeviceSchema.safeParse(req.body);
    if (!parsed.success) {
      throw new BadRequestError(parsed.error.issues.map(i => i.message).join('; '));
    }
    const input = parsed.data;
    const now = new Date().toISOString();
    const productId = getRequestProductId(req);
    const doc: DeviceDoc = {
      id: `dev_${input.userId}_${input.deviceId}`,
      productId,
      ...input,
      lastSeenAt: now,
      createdAt: now,
      updatedAt: now,
    };
    return repo.upsertDevice(doc);
  });

  // List user devices
  app.get('/devices/:userId', async req => {
    const { userId } = req.params as { userId: string };
    const productId = getRequestProductId(req);
    return { devices: await repo.getDevicesByUser(userId, productId) };
  });

  // Remove device
  app.delete('/devices/:id', async req => {
    const { id } = req.params as { id: string };
    const { userId } = req.query as { userId?: string };
    if (!userId) throw new BadRequestError('userId query parameter is required');
    const deleted = await repo.removeDevice(id, userId);
    if (!deleted) throw new NotFoundError('Device not found');
    return { success: true };
  });

  // Get notification prefs
  app.get('/notifications/prefs/:userId', async req => {
    const { userId } = req.params as { userId: string };
    const productId = getRequestProductId(req);
    const prefs = await repo.getPrefs(userId, productId);
    if (!prefs) {
      // Return defaults
      return {
        userId,
        pushEnabled: true,
        emailEnabled: true,
        categories: {},
      };
    }
    return prefs;
  });

  // Update notification prefs
  app.put('/notifications/prefs/:userId', async req => {
    const { userId } = req.params as { userId: string };
    const parsed = UpdatePrefsSchema.safeParse(req.body);
    if (!parsed.success) {
      throw new BadRequestError(parsed.error.issues.map(i => i.message).join('; '));
    }
    const productId = getRequestProductId(req);
    const existing = await repo.getPrefs(userId, productId);
    const now = new Date().toISOString();
    const doc: NotificationPrefsDoc = {
      id: `prefs_${productId}_${userId}`,
      productId,
      userId,
      pushEnabled: parsed.data.pushEnabled ?? existing?.pushEnabled ?? true,
      emailEnabled: parsed.data.emailEnabled ?? existing?.emailEnabled ?? true,
      categories: { ...(existing?.categories ?? {}), ...(parsed.data.categories ?? {}) },
      createdAt: existing?.createdAt ?? now,
      updatedAt: now,
    };
    return repo.upsertPrefs(doc);
  });
}
