import { Tax, Taxes } from "@erp/core/api";
import { InvoiceAmount } from "../../value-objects";

export type InvoiceTaxTotal = {
  tax: Tax;
  taxableAmount: InvoiceAmount;
  taxesAmount: InvoiceAmount;
};

export class InvoiceTaxes extends Taxes {
  constructor(items: Tax[] = [], totalItems: number | null = null) {
    super(items, totalItems);
  }

  public getTaxesAmount(taxableAmount: InvoiceAmount): InvoiceAmount {
    return this.getAll().reduce(
      (total, tax) => total.add(taxableAmount.percentage(tax.percentage)),
      InvoiceAmount.zero(taxableAmount.currencyCode)
    );
  }

  public getTaxesAmountByTaxCode(taxCode: string, taxableAmount: InvoiceAmount): InvoiceAmount {
    const currencyCode = taxableAmount.currencyCode;

    return this.filter((itemTax) => itemTax.code === taxCode).reduce((totalAmount, itemTax) => {
      return taxableAmount.percentage(itemTax.percentage).add(totalAmount);
    }, InvoiceAmount.zero(currencyCode));
  }

  public getTaxesAmountByTaxes(taxableAmount: InvoiceAmount): InvoiceTaxTotal[] {
    return this.getAll().map((taxItem) => ({
      taxableAmount,
      tax: taxItem,
      taxesAmount: this.getTaxesAmountByTaxCode(taxItem.code, taxableAmount),
    }));
  }

  public getCodesToString(): string {
    return this.getAll()
      .map((taxItem) => taxItem.code)
      .join(", ");
  }
}
