import { Presenter } from "@erp/core/api";
import { toEmptyString } from "@repo/rdx-ddd";
import { ArrayElement } from "@repo/rdx-utils";
import { GetCustomerInvoiceByIdResponseDTO } from "../../../../common/dto";
import { CustomerInvoiceItem, CustomerInvoiceItems } from "../../../domain";

type GetCustomerInvoiceItemByInvoiceIdResponseDTO = ArrayElement<
  GetCustomerInvoiceByIdResponseDTO["items"]
>;

export class CustomerInvoiceItemsFullPresenter extends Presenter {
  private _mapItem(
    invoiceItem: CustomerInvoiceItem,
    index: number
  ): GetCustomerInvoiceItemByInvoiceIdResponseDTO {
    const allAmounts = invoiceItem.getAllAmounts();

    return {
      id: invoiceItem.id.toPrimitive(),
      is_non_valued: String(invoiceItem.isNonValued),
      position: String(index),
      description: toEmptyString(invoiceItem.description, (value) => value.toPrimitive()),

      quantity: invoiceItem.quantity.match(
        (quantity) => quantity.toObjectString(),
        () => ({ value: "", scale: "" })
      ),

      unit_amount: invoiceItem.unitAmount.match(
        (unitAmount) => unitAmount.toObjectString(),
        () => ({ value: "", scale: "", currency_code: "" })
      ),

      subtotal_amount: allAmounts.subtotalAmount.toObjectString(),

      discount_percentage: invoiceItem.discountPercentage.match(
        (discountPercentage) => discountPercentage.toObjectString(),
        () => ({ value: "", scale: "" })
      ),

      discount_amount: allAmounts.discountAmount.toObjectString(),

      taxable_amount: allAmounts.taxableAmount.toObjectString(),
      tax_codes: invoiceItem.taxes.getCodesToString().split(","),
      taxes_amount: allAmounts.taxesAmount.toObjectString(),

      total_amount: allAmounts.totalAmount.toObjectString(),
    };
  }

  toOutput(invoiceItems: CustomerInvoiceItems): GetCustomerInvoiceByIdResponseDTO["items"] {
    return invoiceItems.map(this._mapItem);
  }
}
