import {
  ChangeDetectionStrategy,
  Component,
  input,
  inject,
  computed,
  signal,
  effect,
} from '@angular/core';
import { isaActionCheck } from '@isa/icons';
import {
  DisplayOrderItem,
  OrderRewardCollectFacade,
  LoyaltyCollectType,
  OrderItemSubsetResource,
  getProcessingStatusState,
  ProcessingStatusState,
  HandleCommandFacade,
  HandleCommandService,
  HandleCommand,
  getMainActions,
  DisplayOrdersResource,
} from '@isa/oms/data-access';
import { ButtonComponent } from '@isa/ui/buttons';
import { NgIcon } from '@ng-icons/core';
import { provideIcons } from '@ng-icons/core';
import { OrderConfiramtionStore } from '../../../reward-order-confirmation.store';
import {
  DropdownButtonComponent,
  DropdownOptionComponent,
} from '@isa/ui/input-controls';
import {
  hasOrderTypeFeature,
  buildItemQuantityMap,
  hasLoyaltyCollectCommand,
} from '@isa/checkout/data-access';
import { IfRoleDirective, Role } from '@isa/core/auth';

@Component({
  selector: 'checkout-confirmation-list-item-action-card',
  templateUrl: './confirmation-list-item-action-card.component.html',
  styleUrls: ['./confirmation-list-item-action-card.component.css'],
  changeDetection: ChangeDetectionStrategy.OnPush,
  imports: [
    NgIcon,
    ButtonComponent,
    DropdownButtonComponent,
    DropdownOptionComponent,
    IfRoleDirective,
  ],
  providers: [
    provideIcons({ isaActionCheck }),
    OrderItemSubsetResource,
    HandleCommandService,
    HandleCommandFacade,
  ],
})
export class ConfirmationListItemActionCardComponent {
  protected readonly Role = Role;
  LoyaltyCollectType = LoyaltyCollectType;
  ProcessingStatusState = ProcessingStatusState;
  #orderRewardCollectFacade = inject(OrderRewardCollectFacade);
  #store = inject(OrderConfiramtionStore);
  #orderItemSubsetResource = inject(OrderItemSubsetResource);
  #displayOrdersResource = inject(DisplayOrdersResource);
  #handleCommandFacade = inject(HandleCommandFacade);

  item = input.required<DisplayOrderItem>();

  orders = this.#store.orders;

  getOrderBasedOnItem = computed(() => {
    const item = this.item();
    const orders = this.orders();
    if (!orders) {
      return undefined;
    }
    const order = orders.find((order) =>
      order.items?.some((orderItem) => orderItem.id === item.id),
    );
    return order;
  });

  orderItemSubsets = this.#orderItemSubsetResource.orderItemSubsets;
  selectedAction = signal<LoyaltyCollectType>(LoyaltyCollectType.Collect);

  processingStatus = computed(() => {
    const subsets = this.orderItemSubsets();
    const statuses = subsets?.map((subset) => subset.processingStatus);
    return getProcessingStatusState(statuses);
  });
  isLoading = signal(false);
  resourcesLoading = computed(() => {
    return this.isLoading() || this.#orderItemSubsetResource.loading();
  });

  isComplete = computed(() => {
    return (
      this.processingStatus() !== undefined &&
      this.processingStatus() !== ProcessingStatusState.Ordered
    );
  });

  /**
   * #5459 - Determines whether the action card should be displayed for this order item.
   *
   * The action card is shown when ALL of the following conditions are met:
   * - The item MUST have the 'Rücklage' order type feature
   * - AND one of the following:
   *   - The item has a loyalty collect command available (for collecting rewards)
   *   - OR the item processing is complete (for displaying the completed state)
   */
  displayActionCard = computed(
    () =>
      hasOrderTypeFeature(this.item().features, ['Rücklage']) &&
      (hasLoyaltyCollectCommand(this.item().subsetItems) || this.isComplete()),
  );

  constructor() {
    effect(() => {
      const item = this.item();
      const orderItemSubsetIds = item.subsetItems
        ?.map((subset) => subset.id)
        ?.filter((id): id is number => id !== undefined);

      if (orderItemSubsetIds?.length) {
        this.#orderItemSubsetResource.loadOrderItemSubsets(orderItemSubsetIds);
      }
    });
  }

  setDropdownAction(value: LoyaltyCollectType) {
    this.selectedAction.set(value);
  }

  async onCollect() {
    this.isLoading.set(true);
    const item = this.item();
    const order = this.getOrderBasedOnItem();
    const orderItemId = item.id;
    const collectType = this.selectedAction();

    try {
      if (order?.id && orderItemId) {
        for (const subsetItem of item.subsetItems ?? []) {
          const orderItemSubsetId = subsetItem.id;
          const quantity = subsetItem.quantity;

          if (orderItemSubsetId && !!quantity) {
            const res = await this.#orderRewardCollectFacade.collect({
              orderId: order?.id,
              orderItemId,
              orderItemSubsetId,
              collectType,
              quantity,
            });

            const actions = getMainActions(res);

            for (const action of actions) {
              await this.handleCommand({
                action,
                items: res,
                itemQuantity: buildItemQuantityMap(item),
                order,
              });
            }
          }
        }
        this.reloadResources();
      }
    } finally {
      this.isLoading.set(false);
    }
  }

  async handleCommand(params: HandleCommand) {
    await this.#handleCommandFacade.handle(params);
  }

  reloadResources() {
    this.#orderItemSubsetResource.refresh();
    this.#displayOrdersResource.refresh();
  }
}
