import {
  ISequelizeMapper,
  SequelizeMapper,
} from "@/contexts/common/infrastructure";
import {
  City,
  Country,
  Email,
  Note,
  Phone,
  PostalCode,
  Province,
  Street,
  UniqueID,
} from "@shared/contexts";
import { ContactAddress, IContactAddressProps } from "../../domain";
import { IInvoicingContext } from "../InvoicingContext";
import {
  ContactAddress_Model,
  TCreationContactAddress_Attributes,
} from "../sequelize";

export interface IContactAddressMapper
  extends ISequelizeMapper<
    ContactAddress_Model,
    TCreationContactAddress_Attributes,
    ContactAddress
  > {}

export const createContactAddressMapper = (
  context: IInvoicingContext
): IContactAddressMapper => new ContactAddressMapper({ context });

class ContactAddressMapper
  extends SequelizeMapper<
    ContactAddress_Model,
    TCreationContactAddress_Attributes,
    ContactAddress
  >
  implements IContactAddressMapper
{
  protected toDomainMappingImpl(source: ContactAddress_Model, params: any) {
    const id = this.mapsValue(source, "id", UniqueID.create);

    const props: IContactAddressProps = {
      type: source.type,
      street: this.mapsValue(source, "street", Street.create),
      city: this.mapsValue(source, "city", City.create),
      province: this.mapsValue(source, "province", Province.create),
      postalCode: this.mapsValue(source, "postal_code", PostalCode.create),
      country: this.mapsValue(source, "country", Country.create),
      email: this.mapsValue(source, "email", Email.create),
      phone: this.mapsValue(source, "phone", Phone.create),
      notes: this.mapsValue(source, "notes", Note.create),
    };

    const addressOrError = ContactAddress.create(props, id);

    if (addressOrError.isFailure) {
      throw addressOrError.error;
    }

    return addressOrError.object;
  }
}
