import { Collection, Result } from "@repo/rdx-utils";
import { Model } from "sequelize";
import { MapperParamsType } from "../../../domain";
import { ISequelizeQueryMapper } from "./sequelize-mapper.interface";

export abstract class SequelizeQueryMapper<TModel extends Model, TEntity>
  implements ISequelizeQueryMapper<TModel, TEntity>
{
  public abstract mapToDTO(raw: TModel, params?: MapperParamsType): Result<TEntity, Error>;

  public mapToDTOCollection(
    raws: TModel[],
    totalCount: number,
    params?: MapperParamsType
  ): Result<Collection<TEntity>, Error> {
    const _source = raws ?? [];

    try {
      if (_source.length === 0) {
        return Result.ok(new Collection([], totalCount));
      }

      const items = _source.map((value, index) => {
        const result = this.mapToDTO(value as TModel, { index, ...params });
        if (result.isFailure) {
          throw result.error;
        }
        return result.data;
      });
      return Result.ok(new Collection(items, totalCount));
    } catch (error) {
      return Result.fail(error as Error);
    }
  }
}
