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

@Component({
  selector: 'lib-remission-return-receipt-complete',
  templateUrl: './remission-return-receipt-complete.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush,
  imports: [ButtonComponent],
})
export class RemissionReturnReceiptCompleteComponent {
  /** Logger for this component */
  #logger = logger(() => ({
    component: 'RemissionReturnReceiptCompleteComponent',
  }));

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

  /** Service for starting a new remission */
  #remissionStartService = inject(RemissionStartService);

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

  /**
   * Injects a confirmation dialog service for user interactions.
   * This dialog is used to confirm actions like completing a return.
   * The dialog can be customized with title and data options.
   * @example
   * const dialogRef = this.#dialog({
   *   title: 'Wanne abgeschlossen',
   *   data: {
   *     message: 'Legen Sie abschließend den “Blank Beizettel” in die abgeschlossene Wanne.',
   *     closeText: 'Neue Wanne',
   *     confirmText: 'Beenden',
   *   },
   * });
   */
  #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();

  /** Instance of the RemissionStore for managing remission state */
  store = inject(RemissionStore);

  /**
   * Required input for the return ID.
   * Automatically coerced to a number from string input.
   * @input
   * @required
   */
  returnId = input.required<number>();

  /**
   * Required input for the receipt ID.
   * Automatically coerced to a number from string input.
   * @input
   * @required
   */
  receiptId = input.required<number>();

  /**
   * Required input for the number of items in the return.
   * This is used to display the count of items in the return receipt.
   * @input
   * @required
   */
  itemsLength = input.required<number>();

  /**
   * Required input indicating if there is at least one package assigned to the return.
   * @input
   * @required
   */
  hasAssignedPackage = input.required<boolean>();

  /**
   * Output event that emits when the list needs to be reloaded.
   * This is used to refresh the remission list after completing a return.
   * @output
   */
  reloadData = output<void>();

  /**
   * Signal to track if the remission is currently being completed.
   * This prevents multiple submissions while a completion operation is in progress.
   */
  completingRemission = signal(false);

  /**
   * Completes the current remission return receipt.
   * This method handles the completion logic, including confirmation dialogs and navigation.
   * It also emits a reload event to refresh the remission list.
   * @returns {Promise<Return>} The completed return data
   */
  async completeSingleReturnReceipt(): Promise<Return> {
    const completedReturn =
      await this.#remissionReturnReceiptService.completeReturnReceiptAndReturn({
        returnId: this.returnId(),
        receiptId: this.receiptId(),
      });
    this.store.clearState();
    return completedReturn;
  }

  /**
   * Handles the completion of the remission return receipt.
   * It checks if the remission is already being completed to avoid duplicate actions.
   * If not, it proceeds to complete the remission and handle the post-completion logic.
   */
  async completeRemission() {
    if (this.completingRemission()) {
      return;
    }
    this.completingRemission.set(true);

    try {
      // #5289 - Ensure a package is assigned before completing the remission
      if (!this.hasAssignedPackage()) {
        const res = await this.#remissionStartService.assignPackage({
          returnId: this.returnId(),
          receiptId: this.receiptId(),
        });

        if (!res) {
          this.completingRemission.set(false);
          return;
        }
      }

      // Complete Remission Flow
      const completedReturn = await this.completeSingleReturnReceipt();
      const returnGroup = completedReturn?.returnGroup;

      if (returnGroup) {
        const dialogRef = this.#confirmDialog({
          title: 'Wanne abgeschlossen',
          width: '30rem',
          data: {
            message:
              'Legen Sie abschließend den “Blank Beizettel” in die abgeschlossene Wanne. Der Warenbegleitschein wird nach Abschluss der Remission versendet. Zum Öffnen eines neuen Warenbegleitscheins setzen Sie die Remission fort.',
            closeText: 'Neue Wanne',
            confirmText: 'Beenden',
          },
        });
        const dialogResult = await firstValueFrom(dialogRef.closed);

        if (dialogResult?.confirmed) {
          // Beenden - Remission abschließen Flow - Return Group Abschließen
          await this.#remissionReturnReceiptService.completeReturnGroup({
            returnGroup,
          });
        } else {
          // Starten - Neue Wanne Flow
          await this.#remissionStartService.startRemission(returnGroup);
          await this.navigateToRemissionList();
        }
      }

      this.reloadData.emit();
    } catch (error) {
      this.#logger.error('Failed to complete remission', error);
    }
    this.completingRemission.set(false);
  }

  /**
   * Navigates to the remission list.
   */
  async navigateToRemissionList() {
    await this.router.navigate(['/', this.activatedTabId(), 'remission']);
  }
}
