import {
  ISequelizeAdapter,
  SequelizeRepository,
} from "@/contexts/common/infrastructure/sequelize";
import { UniqueID } from "@shared/contexts";
import { Transaction } from "sequelize";
import { Contact, IContactRepository } from "../domain/Contact";
import { IContactMapper } from "./mappers/contact.mapper";

export class ContactRepository
  extends SequelizeRepository<Contact>
  implements IContactRepository
{
  protected mapper: IContactMapper;

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

  public async getById2(
    id: UniqueID,
    billingAddressId: UniqueID,
    shippingAddressId: UniqueID,
  ) {
    const Contact_Model = this.adapter.getModel("Contact_Model");
    const ContactAddress_Model = this.adapter.getModel("ContactAddress_Model");

    const rawContact: any = await Contact_Model.findOne({
      where: { id: id.toString() },
      include: [
        {
          model: ContactAddress_Model,
          as: "billingAddress",
          where: {
            id: billingAddressId.toString(),
          },
        },
        {
          model: ContactAddress_Model,
          as: "shippingAddress",
          where: {
            id: shippingAddressId.toString(),
          },
        },
      ],
      transaction: this.transaction,
    });

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

    return this.mapper.mapToDomain(rawContact);
  }

  public async getById(id: UniqueID): Promise<Contact | null> {
    const rawContact: any = await this._getById("Contact_Model", id, {
      include: [{ all: true }],
    });

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

    return this.mapper.mapToDomain(rawContact);
  }

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