import { Criteria } from "@repo/rdx-criteria/server";
import { UniqueID } from "@repo/rdx-ddd";
import { Collection, Result } from "@repo/rdx-utils";
import { CustomerListDTO } from "../../infrastructure/mappers";
import { Customer } from "../aggregates";

/**
 * Interfaz del repositorio para el agregado `Customer`.
 * El escopado multitenant está representado por `companyId`.
 */
export interface ICustomerRepository {
  /**
   * Guarda (crea o actualiza) un Customer en la base de datos.
   * Retorna el objeto actualizado tras la operación.
   */
  save(customer: Customer, transaction: any): Promise<Result<Customer, Error>>;

  /**
   * Comprueba si existe un Customer con un `id` dentro de una `company`.
   */
  existsByIdInCompany(
    companyId: UniqueID,
    id: UniqueID,
    transaction?: any
  ): Promise<Result<boolean, Error>>;

  /**
   * Recupera un Customer por su ID y companyId.
   * Devuelve un `NotFoundError` si no se encuentra.
   */
  getByIdInCompany(
    companyId: UniqueID,
    id: UniqueID,
    transaction?: any
  ): Promise<Result<Customer, Error>>;

  /**
   * Recupera múltiples customers dentro de una empresa
   * según un criterio dinámico (búsqueda, paginación, etc.).
   * El resultado está encapsulado en un objeto `Collection<T>`.
   */
  findByCriteriaInCompany(
    companyId: UniqueID,
    criteria: Criteria,
    transaction?: any
  ): Promise<Result<Collection<CustomerListDTO>, Error>>;

  /**
   * Elimina un Customer por su ID, dentro de una empresa.
   * Retorna `void` si se elimina correctamente, o `NotFoundError` si no existía.
   *
   */
  deleteByIdInCompany(
    companyId: UniqueID,
    id: UniqueID,
    transaction: any
  ): Promise<Result<void, Error>>;
}
