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

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

import { ViewOrderAction } from '../action/order.action';
import { GetRefundAction, SendRefundRequestAction } from '../action/refund.action';
import { IRefund } from '../interface/refund.interface';
import { RefundService } from '../services/refund.service';

export class RefundStateModel {
  refund = {
    data: [] as IRefund[],
    total: 0,
  };
}

@State<RefundStateModel>({
  name: 'refund',
  defaults: {
    refund: {
      data: [],
      total: 0,
    },
  },
})
@Injectable()
export class RefundState {
  private refundService = inject(RefundService);
  private store = inject(Store);

  @Selector()
  static refund(state: RefundStateModel) {
    return state.refund;
  }

  @Action(GetRefundAction)
  getRefund(ctx: StateContext<RefundStateModel>, action: GetRefundAction) {
    return this.refundService.getRefunds(action.payload).pipe(
      tap({
        next: result => {
          ctx.patchState({
            refund: {
              data: result.data,
              total: result?.total ? result?.total : result.data?.length,
            },
          });
        },
        error: err => {
          throw new Error(err?.error?.message);
        },
      }),
    );
  }

  @Action(SendRefundRequestAction)
  sendRefundStatus(ctx: StateContext<RefundStateModel>, action: SendRefundRequestAction) {
    return this.refundService.sendRefundRequest(action.payload).pipe(
      tap({
        next: result => {
          if (typeof result === 'object') {
            const state = ctx.getState();
            ctx.patchState({
              ...state,
              refund: {
                data: [...state.refund.data, result],
                total: state.refund.total,
              },
            });
            this.store.dispatch(new ViewOrderAction(result.order_number));
          }
        },
        error: err => {
          throw new Error(err?.error?.message);
        },
      }),
    );
  }
}
