// src/server/features/notifications/notifications.routes.ts
// HTTP handlers for notifications API

import { FastifyInstance } from 'fastify';
import { ZodTypeProvider } from 'fastify-type-provider-zod';
import { z } from 'zod';
import { db } from '@serverShared/db/client';
import { pendingNotifications } from './db/pending_notifications.table';
import { eq, desc } from 'drizzle-orm';
import { loggerService } from '@serverShared/lib/logger';

const notificationsLogger = loggerService.get('HTTP').child({ module: 'notifications' });

export const notificationsRoutes = async (fastify: FastifyInstance) => {
  const server = fastify.withTypeProvider<ZodTypeProvider>();
  
  // Get pending notifications for user
  server.get('/notifications/:userId', {
    schema: {
      params: z.object({
        userId: z.string(),
      }),
      response: {
        200: z.array(
          z.object({
            id: z.string(),
            event: z.string(),
            data: z.any(),
            readAt: z.string().nullable(),
            createdAt: z.string(),
          })
        ),
      },
    },
  }, async (request: any) => {
    const { userId } = request.params;
    
      try {
      const notifications = await db
        .select()
        .from(pendingNotifications)
        .where(eq(pendingNotifications.userId, userId))
        .orderBy(desc(pendingNotifications.createdAt)); // DESC: новые сверху, старые снизу
      
      // Конвертируем Date в строки и возвращаем уведомления как они есть в БД
      // Агрегация уже выполнена на уровне service.ts при создании/обновлении уведомлений
      // Если data пришел как строка (JSON), парсим его в объект
      const result = notifications.map(n => ({
        id: n.id,
        event: n.event,
        data: typeof n.data === 'string' ? JSON.parse(n.data) : n.data,
        readAt: n.readAt?.toISOString() || null,
        createdAt: n.createdAt.toISOString(),
      }));
      
      return result;
    } catch (error) {
      notificationsLogger.error('Error getting notifications:', error);
      throw error;
    }
  });
  
  // Mark notification as read
  server.post('/notifications/:id/read', {
    schema: {
      params: z.object({
        id: z.string(),
      }),
      response: {
        200: z.object({
          success: z.boolean(),
          message: z.string(),
        }),
      },
    },
  }, async (request: any) => {
    const { id } = request.params;
    
      try {
      await db
        .update(pendingNotifications)
        .set({ readAt: new Date() })
        .where(eq(pendingNotifications.id, id));
      
      notificationsLogger.info(`Notification ${id} marked as read`);
      return {
        success: true,
        message: 'Notification marked as read',
      };
    } catch (error) {
      notificationsLogger.error('Error marking notification as read:', error);
      throw error;
    }
  });
  
  // Mark all notifications as read for user
  server.post('/notifications/user/:userId/read-all', {
    schema: {
      params: z.object({
        userId: z.string(),
      }),
      response: {
        200: z.object({
          success: z.boolean(),
          message: z.string(),
        }),
      },
    },
  }, async (request: any) => {
    const { userId } = request.params;
    
    try {
      await db
        .update(pendingNotifications)
        .set({ readAt: new Date() })
        .where(eq(pendingNotifications.userId, userId));
      
      notificationsLogger.info(`All notifications marked as read for user ${userId}`);
      return {
        success: true,
        message: 'All notifications marked as read',
      };
    } catch (error) {
      notificationsLogger.error('Error marking all notifications as read:', error);
      throw error;
    }
  });
};
