import { CustomerInvoice, ICustomerInvoiceRepository } from "@/contexts/customer-billing/domain";
import { UniqueID } from "@/core/common/domain";
import { SequelizeRepository } from "@/core/common/infrastructure";
import { Collection, Result } from "@repo/rdx-utils";
import { Transaction } from "sequelize";
import {
  type ICustomerInvoiceMapper,
  customerInvoiceMapper,
} from "../mappers/customer-invoice.mapper";
import { CustomerInvoiceModel } from "./customer-invoice.model";

class CustomerInvoiceRepository
  extends SequelizeRepository<CustomerInvoice>
  implements ICustomerInvoiceRepository
{
  private readonly _mapper!: ICustomerInvoiceMapper;

  /**
   * 🔹 Función personalizada para mapear errores de unicidad en autenticación
   */
  private _customErrorMapper(error: Error): string | null {
    if (error.name === "SequelizeUniqueConstraintError") {
      return "Customer invoice with this email already exists";
    }

    return null;
  }

  constructor(mapper: ICustomerInvoiceMapper) {
    super();
    this._mapper = mapper;
  }

  async findAll(transaction?: Transaction): Promise<Result<Collection<CustomerInvoice>, Error>> {
    try {
      const rawCustomerInvoices: any = await this._findAll(CustomerInvoiceModel, {}, transaction);

      if (!rawCustomerInvoices === true) {
        return Result.fail(new Error("Customer with email not exists"));
      }

      return this._mapper.mapArrayToDomain(rawCustomerInvoices);
    } catch (error: any) {
      return this._handleDatabaseError(error, this._customErrorMapper);
    }
  }

  async findById(id: UniqueID, transaction?: Transaction): Promise<Result<CustomerInvoice, Error>> {
    try {
      const rawInvoice: any = await this._getById(CustomerInvoiceModel, id, {}, transaction);

      if (!rawInvoice === true) {
        return Result.fail(new Error(`Customer with id ${id.toString()} not exists`));
      }

      return this._mapper.mapToDomain(rawInvoice);
    } catch (error: any) {
      return this._handleDatabaseError(error, this._customErrorMapper);
    }
  }
}

const customerInvoiceRepository = new CustomerInvoiceRepository(customerInvoiceMapper);
export { customerInvoiceRepository };
