import { inject, Injectable } from '@angular/core';
import { injectConfirmationDialog, injectFeedbackDialog } from '@isa/ui/dialog';
import { firstValueFrom } from 'rxjs';
import { RewardSelectionService } from './reward-selection.service';
import { CheckoutMetadataService } from '@isa/checkout/data-access';
import { injectTabId } from '@isa/core/tabs';

export const NavigateAfterRewardSelection = {
  CART: 'cart',
  REWARD: 'reward',
  CATALOG: 'catalog',
} as const;
export type NavigateAfterRewardSelection =
  (typeof NavigateAfterRewardSelection)[keyof typeof NavigateAfterRewardSelection];

@Injectable()
export class RewardSelectionPopUpService {
  #tabId = injectTabId();
  #feedbackDialog = injectFeedbackDialog();
  #confirmationDialog = injectConfirmationDialog();
  #rewardSelectionService = inject(RewardSelectionService);
  #checkoutMetadataService = inject(CheckoutMetadataService);

  /**
   * Displays the reward selection popup dialog if conditions are met.
   *
   * This method manages the complete flow of the reward selection popup:
   * 1. Checks if the popup has already been shown in the current tab (prevents duplicate displays)
   * 2. Reloads necessary resources for the reward selection dialog
   * 3. Opens the reward selection dialog if conditions allow
   * 4. Marks the popup as opened for the current tab using {@link #setPopUpOpenedState}
   * 5. Processes user selections and determines navigation flow
   *
   * @returns A promise that resolves to:
   * - `NavigateAfterRewardSelection.CART` - Navigate to the shopping cart
   * - `NavigateAfterRewardSelection.REWARD` - Navigate to the reward cart
   * - `NavigateAfterRewardSelection.CATALOG` - Navigate back to the catalog
   * - `undefined` - Stay on the current page (e.g., when all quantities are set to 0)
   *
   * @example
   * ```typescript
   * const result = await rewardSelectionPopUpService.popUp();
   * if (result === NavigateAfterRewardSelection.CART) {
   *   this.router.navigate(['/cart']);
   * }
   * ```
   */
  async popUp(): Promise<NavigateAfterRewardSelection | undefined> {
    if (this.#popUpAlreadyOpened(this.#tabId())) {
      return NavigateAfterRewardSelection.CART;
    }

    await this.#rewardSelectionService.reloadResources();

    if (this.#rewardSelectionService.canOpen()) {
      const dialogResult = await this.#rewardSelectionService.open({
        closeText: 'Weiter einkaufen',
      });

      this.#setPopUpOpenedState(this.#tabId(), true);

      if (dialogResult) {
        // Wenn der User alles 0 setzt, bleibt man einfach auf der aktuellen Seite
        if (dialogResult?.rewardSelectionItems?.length === 0) {
          await this.#feedback();
          return undefined;
        }

        if (dialogResult.rewardSelectionItems?.length > 0) {
          const hasRegularCartItems = dialogResult.rewardSelectionItems?.some(
            (item) => item?.cartQuantity > 0,
          );
          const hasRewardCartItems = dialogResult.rewardSelectionItems?.some(
            (item) => item?.rewardCartQuantity > 0,
          );

          return await this.#confirmDialog(
            hasRegularCartItems,
            hasRewardCartItems,
          );
        }
      }
    }

    return NavigateAfterRewardSelection.CART;
  }

  async #feedback() {
    this.#feedbackDialog({
      data: { message: 'Auswahl gespeichert' },
    });
  }

  async #confirmDialog(
    hasRegularCartItems: boolean,
    hasRewardCartItems: boolean,
  ): Promise<NavigateAfterRewardSelection | undefined> {
    const title = hasRewardCartItems
      ? 'Artikel wurde der Prämienausgabe hinzugefügt'
      : 'Artikel wurde zum Warenkorb hinzugefügt';

    const message = hasRegularCartItems
      ? 'Bitte schließen sie erst den Warenkorb ab und dann die Prämienausgabe'
      : hasRegularCartItems && !hasRewardCartItems
        ? 'Bitte schließen sie den Warenkorb ab'
        : '';

    const dialogRef = this.#confirmationDialog({
      title,
      data: {
        message,
        closeText: 'Weiter einkaufen',
        confirmText: hasRegularCartItems
          ? 'Zum Warenkorb'
          : 'Zur Prämienausgabe',
      },
      width: '30rem',
    });

    const dialogResult = await firstValueFrom(dialogRef.closed);

    if (dialogResult) {
      if (dialogResult.confirmed && hasRegularCartItems) {
        return NavigateAfterRewardSelection.CART;
      } else if (dialogResult.confirmed) {
        return NavigateAfterRewardSelection.REWARD;
      } else {
        return NavigateAfterRewardSelection.CATALOG;
      }
    }

    return undefined;
  }

  #popUpAlreadyOpened(tabId: number | null): boolean | undefined {
    if (tabId == null) return;
    return this.#checkoutMetadataService.getRewardSelectionPopupOpenedState(
      tabId,
    );
  }

  /**
   * Sets the opened state of the reward selection popup for a specific tab.
   *
   * This method persists the popup state to prevent the popup from being displayed
   * multiple times within the same tab session. It's called after successfully
   * opening the reward selection dialog.
   *
   * @param tabId - The unique identifier of the tab. If null, the method returns early without setting state.
   * @param opened - The opened state to set. `true` indicates the popup has been shown, `false` or `undefined` resets the state.
   *
   * @remarks
   * This state is typically set to `true` after the user has seen the popup to ensure
   * it doesn't appear again during the same browsing session in that tab.
   */
  #setPopUpOpenedState(tabId: number | null, opened: boolean | undefined) {
    if (tabId == null) return;
    this.#checkoutMetadataService.setRewardSelectionPopupOpenedState(
      tabId,
      opened,
    );
  }
}
