import {
  ChangeDetectionStrategy,
  Component,
  inject,
  computed,
  signal,
} from '@angular/core';
import {
  RewardCatalogStore,
  CheckoutMetadataService,
  ShoppingCartFacade,
  SelectedRewardShoppingCartResource,
} from '@isa/checkout/data-access';
import { injectTabId } from '@isa/core/tabs';
import { StatefulButtonComponent, StatefulButtonState } from '@isa/ui/buttons';
import { PurchaseOptionsModalService } from '@modal/purchase-options';
import { firstValueFrom } from 'rxjs';
import { Router } from '@angular/router';
import { getRouteToCustomer } from '../helpers';
import { PrimaryCustomerCardResource } from '@isa/crm/data-access';
import { NavigationStateService } from '@isa/core/navigation';

@Component({
  selector: 'reward-action',
  templateUrl: './reward-action.component.html',
  styleUrl: './reward-action.component.css',
  changeDetection: ChangeDetectionStrategy.OnPush,
  imports: [StatefulButtonComponent],
})
export class RewardActionComponent {
  #router = inject(Router);
  #store = inject(RewardCatalogStore);
  #tabId = injectTabId();

  #navigationState = inject(NavigationStateService);
  #purchasingOptionsModal = inject(PurchaseOptionsModalService);
  #shoppingCartFacade = inject(ShoppingCartFacade);
  #checkoutMetadataService = inject(CheckoutMetadataService);
  #primaryBonudCardResource = inject(PrimaryCustomerCardResource);
  #selectedRewardShoppingCartResource = inject(
    SelectedRewardShoppingCartResource,
  );

  readonly primaryCustomerCardValue =
    this.#primaryBonudCardResource.primaryCustomerCard;

  selectedItems = computed(() => this.#store.selectedItems());

  points = computed(() => this.primaryCustomerCardValue()?.totalPoints ?? 0);

  hasSelectedItems = computed(() => {
    return Object.keys(this.selectedItems() || {}).length > 0;
  });

  addRewardButtonState = signal<StatefulButtonState>('default');
  rewardButtonErrorMessage = signal<string | null>(null);
  purchasingOptionsInProgress = signal(false);

  disableSelectRewardButton = computed(
    () =>
      this.purchasingOptionsInProgress() ||
      !this.hasSelectedItems() ||
      (!!this.primaryCustomerCardValue() && this.points() <= 0),
  );

  async continueToPurchasingOptions() {
    const tabId = this.#tabId();
    const items = Object.values(this.selectedItems() || {});

    if (!items?.length || !tabId || this.disableSelectRewardButton()) {
      return;
    }

    this.purchasingOptionsInProgress.set(true);

    let rewardShoppingCartId =
      this.#checkoutMetadataService.getRewardShoppingCartId(tabId);

    if (!rewardShoppingCartId) {
      rewardShoppingCartId = await this.#createShoppingCart(tabId);
    }

    try {
      const modalRef = await this.#purchasingOptionsModal.open({
        type: 'add',
        tabId,
        shoppingCartId: rewardShoppingCartId,
        items,
        useRedemptionPoints: true,
        preSelectOption: { option: 'in-store' },
        disabledPurchaseOptions: ['b2b-delivery'],
        hideDisabledPurchaseOptions: true,
      });

      const result = await firstValueFrom(modalRef.afterClosed$);

      if (!result?.data) {
        return;
      }
      this.addRewardButtonState.set('success');

      this.#selectedRewardShoppingCartResource.resource.reload();
      if (result.data !== 'continue-shopping') {
        await this.#navigation(tabId);
      }
    } catch (error: any) {
      const errorMessage =
        error?.error?.message ??
        error?.message ??
        'Prämie konnte nicht ausgewählt werden';
      this.rewardButtonErrorMessage.set(errorMessage);
      this.addRewardButtonState.set('error');
    } finally {
      this.#store.clearSelectedItems();
      this.purchasingOptionsInProgress.set(false);
    }
  }

  async #navigation(tabId: number) {
    // If no Customer Card -> No Customer Selected
    if (!this.primaryCustomerCardValue()) {
      const route = getRouteToCustomer(tabId);

      // Preserve context: Store current reward page URL to return to after customer selection
      await this.#navigationState.preserveContext(
        {
          returnUrl: this.#router.url,
        },
        'select-customer',
      );

      await this.#router.navigate(route.path, {
        queryParams: route.queryParams,
      });
    }
  }

  async #createShoppingCart(tabId: number): Promise<number> {
    const shoppingCart = await this.#shoppingCartFacade.createShoppingCart();
    this.#checkoutMetadataService.setRewardShoppingCartId(
      tabId,
      shoppingCart.id,
    );
    return shoppingCart.id!;
  }
}
