import { inject, Injectable } from '@angular/core';

import { Action, Selector, State, StateContext } from '@ngxs/store';
import { tap } from 'rxjs';

import {
  GetNotificationAction,
  MarkAsReadNotificationAction,
  DeleteNotificationAction,
} from '../action/notification.action';
import { INotification } from '../interface/notification.interface';
import { NotificationService } from '../services/notification.service';

export class NotificationStateModel {
  notification = {
    data: [] as INotification[],
    total: 0,
  };
}

@State<NotificationStateModel>({
  name: 'notification',
  defaults: {
    notification: {
      data: [],
      total: 0,
    },
  },
})
@Injectable()
export class NotificationState {
  private notificationService = inject(NotificationService);

  @Selector()
  static notification(state: NotificationStateModel) {
    return state.notification.data;
  }

  @Action(GetNotificationAction)
  getNotification(ctx: StateContext<NotificationStateModel>, action: GetNotificationAction) {
    return this.notificationService.getNotifications(action?.payload).pipe(
      tap({
        next: result => {
          ctx.patchState({
            notification: {
              data: result.data,
              total: result?.total ? result?.total : result.data.length,
            },
          });
        },
        error: err => {
          throw new Error(err?.error?.message);
        },
      }),
    );
  }

  @Action(MarkAsReadNotificationAction)
  markAsRead(ctx: StateContext<NotificationStateModel>) {
    return this.notificationService.markAsReadNotification().pipe(
      tap({
        next: result => {
          ctx.patchState({
            notification: {
              data: result.data,
              total: result?.total ? result?.total : result.data.length,
            },
          });
        },
        error: err => {
          throw new Error(err?.error?.message);
        },
      }),
    );
  }

  @Action(DeleteNotificationAction)
  delete(ctx: StateContext<NotificationStateModel>, { id }: DeleteNotificationAction) {
    return this.notificationService.deleteNotification(id).pipe(
      tap({
        next: () => {
          const state = ctx.getState();
          let notification = state.notification.data.filter(value => value.id !== id);
          ctx.patchState({
            ...state,
            notification: {
              data: notification,
              total: state.notification.total - 1,
            },
          });
        },
        complete: () => {
          this.notificationService.showSuccess('Notification Deleted Successfully.');
        },
        error: err => {
          throw new Error(err?.error?.message);
        },
      }),
    );
  }
}
