import {
  ChangeDetectionStrategy,
  Component,
  computed,
  inject,
  input,
} from "@angular/core";
import { Location } from "@angular/common";
import {
  isaActionChevronRight,
  isaActionClose,
  isaActionEdit,
} from "@isa/icons";
import {
  EligibleForReturn,
  EligibleForReturnState,
  ReturnProcess,
  ReturnProcessService,
  ProductCategory,
  returnDetailsMapping,
} from "@isa/oms/data-access";
import { ReturnProductInfoComponent } from "@isa/oms/shared/product-info";
import { IconButtonComponent } from "@isa/ui/buttons";
import { NgIcon, provideIcons } from "@ng-icons/core";

/**
 * Displays a single item in the return process summary, showing product details
 * and collected return information.
 *
 * Features:
 * - Displays product information
 * - Shows return details (condition, reason, etc.)
 * - Provides edit functionality
 * - Uses reactive signals for efficient updates
 *
 * The component uses several data attributes for E2E testing:
 * - data-what="list-item": Identifies this as a list item component
 * - data-which="return-process-item": Specifies this as a return process item
 * - data-receipt-id: Dynamic attribute showing the receipt ID for the return
 * - data-return-item-id: Dynamic attribute showing the return item's ID
 *
 * @example
 * ```html
 * <oms-feature-return-summary-item
 *   [returnProcess]="returnProcessObject"
 * ></oms-feature-return-summary-item>
 * ```
 */
@Component({
  selector: "oms-feature-return-summary-item",
  templateUrl: "./return-summary-item.component.html",
  styleUrls: ["./return-summary-item.component.scss"],
  changeDetection: ChangeDetectionStrategy.OnPush,
  imports: [ReturnProductInfoComponent, NgIcon, IconButtonComponent],
  providers: [
    provideIcons({ isaActionChevronRight, isaActionEdit, isaActionClose }),
  ],
  host: {
    "data-what": "list-item",
    "data-which": "return-process-item",
    "[attr.data-receipt-id]": "returnProcess()?.receiptId",
    "[attr.data-return-item-id]": "returnProcess()?.returnItem?.id",
  },
})
export class ReturnSummaryItemComponent {
  EligibleForReturnState = EligibleForReturnState;
  #returnProcessService = inject(ReturnProcessService);

  /** Angular Location service for navigation */
  location = inject(Location);

  /** The return process object containing all information about the return */
  returnProcess = input.required<ReturnProcess>();

  /** The status of the return items and print receipt operation */
  returnItemsAndPrintReciptPending = input<boolean>(false);

  /**
   * Computes whether the current return process is eligible for return.
   *
   * This computed signal evaluates the current return process data and determines
   * its eligibility status by calling the return process service. The eligibility
   * information contains the state (e.g., eligible, ineligible) and potentially
   * additional details about why a return may or may not be allowed.
   *
   * @returns An EligibleForReturn object containing eligibility status and details,
   *          or undefined if no valid return process is available
   */
  eligibleForReturn = computed<EligibleForReturn | undefined>(() => {
    const returnProcess = this.returnProcess();
    return this.#returnProcessService.eligibleForReturn(returnProcess);
  });

  /**
   * Computes an array of strings representing detailed return information for the current return process.
   *
   * The returned array may include:
   * - Item condition (if not a Tolino product)
   * - Return reason (if not a Tolino product)
   * - Mapped return details (via {@link returnDetailsMapping})
   * - Information about an incorrectly delivered product (EAN)
   * - Any user-provided comment
   *
   * Duplicates are removed from the result.
   *
   * @returns {string[]} An array of unique, human-readable return information strings.
   *
   * @remarks
   * - If no return info is available, returns an empty array.
   * - The order of information is: item condition, return reason, return details, other product, comment.
   * - For Tolino products, item condition and return reason are omitted.
   */
  returnInfos = computed<string[]>(() => {
    const returnProcess = this.returnProcess();
    const result: string[] = [];

    const returnInfo = this.#returnProcessService.getReturnInfo(returnProcess);

    if (!returnInfo) {
      return result;
    }

    const {
      comment,
      itemCondition,
      otherProduct,
      returnReason,
      returnDetails,
    } = returnInfo;

    if (returnProcess.productCategory !== ProductCategory.Tolino) {
      if (itemCondition) {
        result.push(itemCondition);
      }

      if (returnReason) {
        result.push(returnReason);
      }
    }

    if (returnDetails) {
      result.push(...returnDetailsMapping(returnDetails));
    }

    if (otherProduct) {
      result.push(`Geliefert wurde: ${otherProduct.ean}`);
    }

    if (comment) {
      result.push(comment);
    }

    // remove duplicates
    return Array.from(new Set(result));
  });
}
