import { ISequelizeAdapter, SequelizeRepository } from "@/contexts/common/infrastructure/sequelize";
import { UniqueID } from "@shared/contexts";
import { Transaction } from "sequelize";
import { IProfileContext } from ".";
import { IProfileRepository, Profile } from "../domain";
import { IProfileMapper, createProfileMapper } from "./mappers";

export class ProfileRepository extends SequelizeRepository<Profile> implements IProfileRepository {
  protected mapper: IProfileMapper;

  public constructor(props: {
    mapper: IProfileMapper;
    adapter: ISequelizeAdapter;
    transaction: Transaction;
  }) {
    const { adapter, mapper, transaction } = props;
    super({ adapter, transaction });
    this.mapper = mapper;
  }

  public async exists(id: UniqueID): Promise<boolean> {
    return this._exists("Dealer_Model", "id", id.toPrimitive());
  }

  public async getById(id: UniqueID): Promise<Profile | null> {
    const rawProfile: any = await this._getById("Dealer_Model", id);

    if (!rawProfile === true) {
      return null;
    }

    return this.mapper.mapToDomain(rawProfile);
  }

  public async update(profile: Profile): Promise<void> {
    const userData = this.mapper.mapToPersistence(profile);

    // borrando y luego creando
    // await this.removeById(user.id, true);
    await this._save("Dealer_Model", profile.id, userData, {});
  }

  public async getByUserId(userId: UniqueID): Promise<Profile | null> {
    const rawDealer: any = await this._getBy("Dealer_Model", "user_id", userId.toPrimitive());

    if (!rawDealer === true) {
      return null;
    }

    return this.mapper.mapToDomain(rawDealer);
  }
}

export const registerProfileRepository = (context: IProfileContext) => {
  const adapter = context.adapter;
  const repoManager = context.repositoryManager;

  repoManager.registerRepository("Profile", (params = { transaction: null }) => {
    const { transaction } = params;

    return new ProfileRepository({
      transaction,
      adapter,
      mapper: createProfileMapper(context),
    });
  });
};
