import {
  ChangeDetectionStrategy,
  Component,
  computed,
  effect,
  inject,
  untracked,
} from '@angular/core';
import { toSignal } from '@angular/core/rxjs-interop';

import { OrderConfirmationAddressesComponent } from './order-confirmation-addresses/order-confirmation-addresses.component';
import { OrderConfirmationHeaderComponent } from './order-confirmation-header/order-confirmation-header.component';
import { OrderConfirmationItemListComponent } from './order-confirmation-item-list/order-confirmation-item-list.component';
import { ActivatedRoute } from '@angular/router';
import {
  NavigateBackButtonComponent,
  TabService,
  injectTabId,
} from '@isa/core/tabs';
import { OrderConfiramtionStore } from './reward-order-confirmation.store';
import {
  DisplayOrdersResource,
  getProcessingStatusState,
  ProcessingStatusState,
} from '@isa/oms/data-access';
import {
  hasOrderTypeFeature,
  hasLoyaltyCollectCommand,
} from '@isa/checkout/data-access';

@Component({
  selector: 'checkout-reward-order-confirmation',
  templateUrl: './reward-order-confirmation.component.html',
  styleUrls: ['./reward-order-confirmation.component.css'],
  changeDetection: ChangeDetectionStrategy.OnPush,
  imports: [
    OrderConfirmationHeaderComponent,
    OrderConfirmationAddressesComponent,
    OrderConfirmationItemListComponent,
    NavigateBackButtonComponent,
  ],
  providers: [OrderConfiramtionStore, DisplayOrdersResource],
})
export class RewardOrderConfirmationComponent {
  #store = inject(OrderConfiramtionStore);
  #displayOrdersResource = inject(DisplayOrdersResource);
  #tabId = injectTabId();
  #activatedRoute = inject(ActivatedRoute);

  params = toSignal(this.#activatedRoute.paramMap);

  displayOrderIds = computed(() => {
    const params = this.params();
    if (!params) {
      return [];
    }
    const param = params.get('displayOrderIds');
    return param ? param.split(',').map((strId) => parseInt(strId, 10)) : [];
  });

  // Expose for testing
  orderIds = this.displayOrderIds;
  orders = this.#store.orders;

  /**
   * Checks if there are any items with pending actions (Rücklage items that still need to be collected).
   * Returns true if at least one item requires action.
   */
  hasPendingActions = computed(() => {
    const orders = this.#store.orders();
    if (!orders) {
      return false;
    }

    const allItems = orders.flatMap((order) => order.items ?? []);

    return allItems.some((item) => {
      const isRuecklage = hasOrderTypeFeature(item.features, ['Rücklage']);
      if (!isRuecklage) {
        return false;
      }

      const hasCollectCommand = hasLoyaltyCollectCommand(item.subsetItems);
      const statuses = item.subsetItems?.map(
        (subset) => subset.processingStatus,
      );
      const processingStatus = getProcessingStatusState(statuses);
      const isComplete =
        processingStatus !== undefined &&
        processingStatus !== ProcessingStatusState.Ordered;

      // Item has pending action if it has collect command and is not complete
      return hasCollectCommand && !isComplete;
    });
  });

  /**
   * Route to the reward catalog for the current tab.
   */
  rewardCatalogRoute = computed(() => `/${this.#tabId()}/reward`);

  constructor() {
    // Update store state
    effect(() => {
      const tabId = this.#tabId() || undefined;
      const orderIds = this.displayOrderIds();

      untracked(() => {
        this.#store.patch({ tabId, orderIds });
      });
    });

    // Load display orders when orderIds change
    effect(() => {
      const orderIds = this.displayOrderIds();

      untracked(() => {
        this.#displayOrdersResource.loadOrders(orderIds);
      });
    });
  }
}
