import {
  ValidationErrorCollection,
  ValidationErrorDetail,
  extractOrPushError,
  maybeFromNullableVO,
} from "@repo/rdx-ddd";
import { Result } from "@repo/rdx-utils";
import { CreateCustomerInvoiceRequestDTO } from "../../../common";
import {
  CustomerInvoiceItem,
  CustomerInvoiceItemDescription,
  CustomerInvoiceItemProps,
  ItemAmount,
  ItemDiscount,
  ItemQuantity,
} from "../../domain";
import { hasNoUndefinedFields } from "./has-no-undefined-fields";

export function mapDTOToCustomerInvoiceItemsProps(
  dtoItems: Pick<CreateCustomerInvoiceRequestDTO, "items">["items"]
): Result<CustomerInvoiceItem[], ValidationErrorCollection> {
  const errors: ValidationErrorDetail[] = [];
  const items: CustomerInvoiceItem[] = [];

  dtoItems.forEach((item, index) => {
    const path = (field: string) => `items[${index}].${field}`;

    const description = extractOrPushError(
      maybeFromNullableVO(item.description, (value) =>
        CustomerInvoiceItemDescription.create(value)
      ),
      path("description"),
      errors
    );

    const quantity = extractOrPushError(
      maybeFromNullableVO(item.quantity, (value) => ItemQuantity.create({ value })),
      path("quantity"),
      errors
    );

    const unitAmount = extractOrPushError(
      maybeFromNullableVO(item.unit_amount, (value) => ItemAmount.create({ value })),
      path("unit_amount"),
      errors
    );

    const discountPercentage = extractOrPushError(
      maybeFromNullableVO(item.discount_percentage, (value) => ItemDiscount.create({ value })),
      path("discount_percentage"),
      errors
    );

    if (errors.length === 0) {
      const itemProps: CustomerInvoiceItemProps = {
        description: description,
        quantity: quantity,
        unitAmount: unitAmount,
        discountPercentage: discountPercentage,
        //currencyCode,
        //languageCode,
        //taxes:
      };

      if (hasNoUndefinedFields(itemProps)) {
        // Validar y crear el item de factura
        const itemOrError = CustomerInvoiceItem.create(itemProps);

        if (itemOrError.isSuccess) {
          items.push(itemOrError.data);
        } else {
          errors.push({ path: `items[${index}]`, message: itemOrError.error.message });
        }
      }
    }

    if (errors.length > 0) {
      return Result.fail(new ValidationErrorCollection("Invoice items dto mapping failed", errors));
    }
  });

  return Result.ok(items);
}
