import { Presenter } from "@erp/core/api";
import { toEmptyString } from "@repo/rdx-ddd";
import { GetCustomerInvoiceByIdResponseDTO } from "../../../../common/dto";
import { CustomerInvoice } from "../../../domain";
import { CustomerInvoiceItemsFullPresenter } from "./customer-invoice-items.full.presenter";
import { RecipientInvoiceFullPresenter } from "./recipient-invoice.full.representer";

export class CustomerInvoiceFullPresenter extends Presenter<
  CustomerInvoice,
  GetCustomerInvoiceByIdResponseDTO
> {
  toOutput(invoice: CustomerInvoice): GetCustomerInvoiceByIdResponseDTO {
    const itemsPresenter = this.presenterRegistry.getPresenter({
      resource: "customer-invoice-items",
      projection: "FULL",
    }) as CustomerInvoiceItemsFullPresenter;

    const recipientPresenter = this.presenterRegistry.getPresenter({
      resource: "recipient-invoice",
      projection: "FULL",
    }) as RecipientInvoiceFullPresenter;

    const recipient = recipientPresenter.toOutput(invoice);
    const items = itemsPresenter.toOutput(invoice.items);
    const allAmounts = invoice.getAllAmounts();

    const payment = invoice.paymentMethod.match(
      (payment) => {
        const { id, payment_description } = payment.toObjectString();
        return {
          payment_id: id,
          payment_description,
        };
      },
      () => undefined
    );

    const invoiceTaxes = invoice.getTaxes().map((taxItem) => {
      return {
        tax_code: taxItem.tax.code,
        taxable_amount: taxItem.taxableAmount.toObjectString(),
        taxes_amount: taxItem.taxesAmount.toObjectString(),
      };
    });

    return {
      id: invoice.id.toString(),
      company_id: invoice.companyId.toString(),

      invoice_number: toEmptyString(invoice.invoiceNumber, (value) => value.toString()),
      status: invoice.status.toPrimitive(),
      series: toEmptyString(invoice.series, (value) => value.toString()),

      invoice_date: invoice.invoiceDate.toDateString(),
      operation_date: toEmptyString(invoice.operationDate, (value) => value.toDateString()),

      reference: toEmptyString(invoice.reference, (value) => value.toString()),
      description: toEmptyString(invoice.description, (value) => value.toString()),
      notes: toEmptyString(invoice.notes, (value) => value.toString()),

      language_code: invoice.languageCode.toString(),
      currency_code: invoice.currencyCode.toString(),

      customer_id: invoice.customerId.toString(),
      recipient,

      taxes: invoiceTaxes,

      payment_method: payment,

      subtotal_amount: allAmounts.subtotalAmount.toObjectString(),

      discount_percentage: invoice.discountPercentage.toObjectString(),

      discount_amount: allAmounts.discountAmount.toObjectString(),
      taxable_amount: allAmounts.taxableAmount.toObjectString(),
      taxes_amount: allAmounts.taxesAmount.toObjectString(),
      total_amount: allAmounts.totalAmount.toObjectString(),

      items,

      metadata: {
        entity: "customer-invoices",
        link: "",
      },
    };
  }
}
