import {
  effect,
  inject,
  Injectable,
  resource,
  signal,
  untracked,
} from '@angular/core';
import { TabService } from '@isa/core/tabs';
import { CheckoutMetadataService } from '../services';
import { ShoppingCartService } from '../services';
import { ShoppingCartEvents } from '../shopping-cart.events';
import { isEqual } from 'lodash';

@Injectable()
export class ShoppingCartResource {
  #shoppingCartService = inject(ShoppingCartService);
  #shoppingCartEvents = inject(ShoppingCartEvents).events;

  #params = signal<number | undefined>(undefined);

  constructor() {
    effect(() => {
      const event = this.#shoppingCartEvents();
      const id = untracked(() => this.#params());
      const value = untracked(() => this.resource.value());

      if (id === undefined) {
        return;
      }

      if (!event) {
        return;
      }

      if (isEqual(value, event.shoppingCart)) {
        return;
      }

      if (event.shoppingCart.id !== id) {
        return;
      }

      this.resource.set(event.shoppingCart);
      console.log('ShoppingCartResource updated from event', {
        event: event.event,
        shoppingCartId: event.shoppingCart.id,
        source: event.source,
      });
    });
  }

  setShoppingCartId(shoppingCartId: number | undefined) {
    this.#params.set(shoppingCartId);

    if (shoppingCartId === undefined) {
      this.resource.set(undefined);
    }
  }

  readonly resource = resource({
    params: () => this.#params(),
    loader: ({ params, abortSignal }) =>
      this.#shoppingCartService.getShoppingCart(params, abortSignal),
  });
}

@Injectable({ providedIn: 'root' })
export class SelectedShoppingCartResource extends ShoppingCartResource {
  #tabId = inject(TabService).activatedTabId;
  #checkoutMetadata = inject(CheckoutMetadataService);

  constructor() {
    super();

    effect(() => {
      const tabId = this.#tabId();
      const shoppingCartId = tabId
        ? this.#checkoutMetadata.getShoppingCartId(tabId)
        : undefined;

      this.setShoppingCartId(shoppingCartId);
    });
  }
}

@Injectable({ providedIn: 'root' })
export class SelectedRewardShoppingCartResource extends ShoppingCartResource {
  #tabId = inject(TabService).activatedTabId;
  #checkoutMetadata = inject(CheckoutMetadataService);

  constructor() {
    super();

    effect(() => {
      const tabId = this.#tabId();
      const shoppingCartId = tabId
        ? this.#checkoutMetadata.getRewardShoppingCartId(tabId)
        : undefined;

      this.setShoppingCartId(shoppingCartId);
    });
  }
}
