import { ISequelizeDomainMapper, MapperParamsType, SequelizeDomainMapper } from "@erp/core/api";
import {
  UniqueID,
  ValidationErrorCollection,
  ValidationErrorDetail,
  extractOrPushError,
  maybeFromNullableVO,
} from "@repo/rdx-ddd";
import { Result } from "@repo/rdx-utils";
import { InferCreationAttributes } from "sequelize";
import { VerifactuRecord, VerifactuRecordProps } from "../../../domain";
import { VerifactuRecordCreationAttributes, VerifactuRecordModel } from "../../sequelize";

export interface IVerifactuRecordDomainMapper
  extends ISequelizeDomainMapper<
    VerifactuRecordModel,
    VerifactuRecordCreationAttributes,
    VerifactuRecord
  > {}

export class VerifactuRecordDomainMapper
  extends SequelizeDomainMapper<
    VerifactuRecordModel,
    VerifactuRecordCreationAttributes,
    VerifactuRecord
  >
  implements IVerifactuRecordDomainMapper
{
  constructor(params: MapperParamsType) {
    super();
  }

  private mapAttributesToDomain(source: VerifactuRecordModel, params?: MapperParamsType) {
    const { errors, index, attributes } = params as {
      index: number;
      errors: ValidationErrorDetail[];
      attributes: Partial<VerifactuRecordProps>;
    };

    const Id = extractOrPushError(UniqueID.create(source.id), `items[${index}].id`, errors);

    const estado = extractOrPushError(
      maybeFromNullableVO(source.estado, (value) => VerifactuRecordEstado.create(value)),
      `items[${index}].estado`,
      errors
    );
    /*
    const quantity = extractOrPushError(
      maybeFromNullableVO(source.quantity_value, (value) => ItemQuantity.create({ value })),
      `items[${index}].discount_percentage`,
      errors
    );

    const unitAmount = extractOrPushError(
      maybeFromNullableVO(source.unit_amount_value, (value) =>
        ItemAmount.create({ value, currency_code: attributes.currencyCode!.code })
      ),
      `items[${index}].unit_amount`,
      errors
    );
*/
    return {
      Id,
      estado,
    };
  }

  public mapToDomain(
    source: VerifactuRecordModel,
    params?: MapperParamsType
  ): Result<VerifactuRecord, Error> {
    const { errors, index, requireIncludes } = params as {
      index: number;
      requireIncludes: boolean;
      errors: ValidationErrorDetail[];
      attributes: Partial<VerifactuRecordProps>;
    };

    // 1) Valores escalares (atributos generales)
    const attributes = this.mapAttributesToDomain(source, params);

    // 2) Comprobar relaciones
    /*    if (requireIncludes) {
      if (!source.taxes) {
        errors.push({
          path: `items[${index}].taxes`,
          message: "Taxes not included in query (requireIncludes=true)",
        });
      }
    }
*/
    // 5) Construcción del elemento de dominio

    const createResult = VerifactuRecord.create({
      id: attributes.Id,
      //invoiceId: attributes.invoiveID
      estado: attributes.estado!,
      url: attributes.url!,
      qr1: attributes.qr1,
    });

    if (createResult.isFailure) {
      return Result.fail(
        new ValidationErrorCollection("Verifactu record entity creation failed", [
          { path: `items[${index}]`, message: createResult.error.message },
        ])
      );
    }

    return createResult;
  }

  public mapToPersistence(
    source: VerifactuRecord,
    params?: MapperParamsType
  ): Result<InferCreationAttributes<VerifactuRecordModel, {}>, Error> {
    throw new Error("not implemented");
  }
}
