import {
  ChangeDetectionStrategy,
  Component,
  computed,
  inject,
  input,
  output,
} from '@angular/core';
import {
  Return,
  getReceiptItemQuantityFromReturn,
  RemissionStore,
  RemissionReturnReceiptService,
} from '@isa/remission/data-access';
import { ButtonComponent } from '@isa/ui/buttons';
import { logger } from '@isa/core/logging';
import { Router } from '@angular/router';
import { injectConfirmationDialog } from '@isa/ui/dialog';
import { injectTabId } from '@isa/core/tabs';
import { firstValueFrom } from 'rxjs';

@Component({
  selector: 'lib-remission-return-receipt-actions',
  templateUrl: './remission-return-receipt-actions.component.html',
  styleUrl: './remission-return-receipt-actions.component.scss',
  changeDetection: ChangeDetectionStrategy.OnPush,
  imports: [ButtonComponent],
})
export class RemissionReturnReceiptActionsComponent {
  /**
   * Remission store for managing remission state.
   */
  #remissionStore = inject(RemissionStore);

  /**
   * Service for handling remission return receipt operations.
   */
  #remissionReturnReceiptService = inject(RemissionReturnReceiptService);

  /** Angular Router for navigation */
  router = inject(Router);

  /**
   * Dialog service for confirmation prompts.
   */
  #confirmDialog = injectConfirmationDialog();

  /**
   * Injects the current activated tab ID as a signal.
   * This is used to determine if the current remission matches the active tab.
   */
  activatedTabId = injectTabId();

  /** Logger for this component */
  #logger = logger(() => ({
    component: 'RemissionReturnReceiptActionsComponent',
  }));

  /** displayDeleteAction - Determines if the delete action should be displayed */
  displayDeleteAction = input<boolean>(true);

  /**
   * Input for the remission return data.
   * @input
   */
  remissionReturn = input.required<Return>();

  /**
   * Output event that emits when the list needs to be reloaded.
   * @output
   */
  reloadData = output<void>();

  /**
   * Computed signal that retrieves the return ID from the remission return data.
   * This is used to identify the specific return for operations like deletion or continuation.
   * @returns {number} The ID of the remission return
   */
  returnId = computed(() => this.remissionReturn().id);

  /**
   * Computed signal that retrieves all receipt IDs associated with the remission return.
   * This is used to manage multiple receipts within a single return.
   * @returns {Array<number>} Array of receipt IDs
   */
  receiptIds = computed(() => {
    return this.remissionReturn().receipts?.map((r) => r.id) || [];
  });

  /**
   * Computed signal that retrieves the first receipt ID from the remission return.
   * This is useful for operations that require a single receipt ID, such as starting a remission.
   * @returns {number | undefined} The first receipt ID or undefined if no receipts exist
   */
  firstReceiptId = computed(() => {
    const receiptIds = this.receiptIds();
    return receiptIds.length > 0 ? receiptIds[0] : undefined;
  });

  /**
   * Computed signal that calculates the total item quantity from all receipts in the return.
   * Uses the helper function to get the quantity.
   * @returns {number} The total item quantity from all receipts
   */
  itemQuantity = computed(() => {
    const returnData = this.remissionReturn();
    return getReceiptItemQuantityFromReturn(returnData);
  });

  /**
   * Computed signal that checks if the current remission is the one being displayed.
   * This is used to determine if the return is currently active in the remission flow.
   * @returns {boolean} True if the current remission matches, false otherwise
   */
  isCurrentRemission = computed(() => {
    const returnId = this.returnId();
    const receiptIds = this.receiptIds();
    const currentReceiptId = this.#remissionStore?.receiptId();
    const currentlyOpenReceiptId = receiptIds?.find(
      (id) => currentReceiptId === id,
    );

    if (!currentlyOpenReceiptId) {
      return false;
    }

    return this.#remissionStore.isCurrentRemission({
      returnId,
      receiptId: currentlyOpenReceiptId,
    });
  });

  /**
   * Method to delete the return receipt.
   * This method handles the deletion of the return and its associated receipts.
   * It checks if the return is the current remission and clears the store state if necessary.
   * Emits the reloadList event after successful deletion to refresh the list.
   * @returns {Promise<void>} A promise that resolves when the deletion is complete
   */
  async onDelete(): Promise<void> {
    try {
      const returnId = this.returnId();
      const receiptIds = this.receiptIds();

      for (const receiptId of receiptIds) {
        if (this.isCurrentRemission()) {
          this.#remissionStore.clearState();
        }

        await this.#remissionReturnReceiptService.cancelReturnReceipt({
          returnId,
          receiptId,
        });
      }

      await this.#remissionReturnReceiptService.cancelReturn({
        returnId,
      });
    } catch (error) {
      this.#logger.error('Error deleting return receipt', error);
      console.error('Error deleting return receipt:', error);
    }

    this.reloadData.emit();
  }

  /**
   * Method to continue with the remission process.
   * If the remission is already started, it navigates to the remission list.
   * If not, it checks if there is a first receipt ID and starts the remission with it.
   * If a remission is already in progress, it prompts the user to either continue with the current remission or start a new one.
   * @returns {Promise<void>} A promise that resolves when navigation is complete
   */
  async onContinueRemission() {
    if (!this.#remissionStore.remissionStarted()) {
      const firstReceiptId = this.firstReceiptId();
      if (firstReceiptId) {
        this.#remissionStore.startRemission({
          returnId: this.returnId(),
          receiptId: firstReceiptId,
        });

        return await this.navigateToRemissionList();
      }
    } else if (!this.isCurrentRemission()) {
      const dialogRef = this.#confirmDialog({
        title: 'Bereits geöffneter Warenbegleitschein',
        width: '30rem',
        data: {
          message:
            'Möchten Sie wirklich einen neuen öffnen, oder möchten Sie zuerst den aktuellen abschließen?',
          closeText: 'Aktuellen bearbeiten',
          confirmText: 'Neuen öffnen',
        },
      });
      const dialogResult = await firstValueFrom(dialogRef.closed);
      // Neuen WBS öffnen
      if (dialogResult?.confirmed) {
        this.#remissionStore.clearState(); // Alte Remission im Store zurücksetzen
        const firstReceiptId = this.firstReceiptId();
        if (firstReceiptId) {
          this.#remissionStore.startRemission({
            returnId: this.returnId(),
            receiptId: firstReceiptId,
          });
        }
      }
    }

    await this.navigateToRemissionList();
  }

  /**
   * Navigates to the remission list based on the current activated tab ID.
   * This method is used to redirect the user to the remission list after completing or starting a remission.
   * @returns {Promise<void>} A promise that resolves when navigation is complete
   */
  async navigateToRemissionList() {
    await this.router.navigate(['/', this.activatedTabId(), 'remission']);
  }
}
