import { GetAllNotificationsUseCase } from '@core/notifications/application/use-cases/GetAllNotificationsUseCase';
import { GetUnreadNotificationsUseCase } from '@core/notifications/application/use-cases/GetUnreadNotificationsUseCase';
import { MarkNotificationReadUseCase } from '@core/notifications/application/use-cases/MarkNotificationReadUseCase';
import { Inject, Injectable } from '@nestjs/common';
import {
    GET_ALL_NOTIFICATIONS_USE_CASE_TOKEN,
    GET_UNREAD_NOTIFICATIONS_USE_CASE_TOKEN,
    MARK_NOTIFICATION_READ_USE_CASE_TOKEN,
} from './NotificationsTokens';

@Injectable()
export class NotificationsService {
  constructor(
    @Inject(GET_UNREAD_NOTIFICATIONS_USE_CASE_TOKEN)
    private readonly getUnreadNotificationsUseCase: GetUnreadNotificationsUseCase,
    @Inject(GET_ALL_NOTIFICATIONS_USE_CASE_TOKEN)
    private readonly getAllNotificationsUseCase: GetAllNotificationsUseCase,
    @Inject(MARK_NOTIFICATION_READ_USE_CASE_TOKEN)
    private readonly markNotificationReadUseCase: MarkNotificationReadUseCase,
  ) {}

  async getUnreadNotifications(userId: string): Promise<Array<Record<string, unknown>>> {
    const result = await this.getUnreadNotificationsUseCase.execute({ recipientId: userId });
    if (result.isErr()) {
      throw new Error(result.unwrapErr().details?.message || 'Failed to get unread notifications');
    }
    return result.unwrap().notifications.map(n => n.toJSON() as Record<string, unknown>);
  }

  async getAllNotifications(userId: string): Promise<Array<Record<string, unknown>>> {
    const result = await this.getAllNotificationsUseCase.execute({ recipientId: userId });
    if (result.isErr()) {
      throw new Error(result.unwrapErr().details?.message || 'Failed to get all notifications');
    }
    return result.unwrap().notifications.map(n => n.toJSON() as Record<string, unknown>);
  }

  async markAsRead(notificationId: string, userId: string): Promise<void> {
    const result = await this.markNotificationReadUseCase.execute({
      notificationId,
      recipientId: userId,
    });
    
    if (result.isErr()) {
      throw new Error(result.unwrapErr().details?.message || 'Failed to mark notification as read');
    }
  }
}
