import {
  ISequelizeMapper,
  MapperParamsType,
  SequelizeMapper,
} from "@/contexts/common/infrastructure";
import { CurrencyData, KeyValueMap, Language, Name, UniqueID } from "@shared/contexts";
import { Dealer, DealerLogotype, DealerStatus, IDealerProps } from "../../domain/entities";
import { ISalesContext } from "../Sales.context";
import { DealerCreationAttributes, Dealer_Model } from "../sequelize";

export interface IDealerMapper
  extends ISequelizeMapper<Dealer_Model, DealerCreationAttributes, Dealer> {}

class DealerMapper
  extends SequelizeMapper<Dealer_Model, DealerCreationAttributes, Dealer>
  implements IDealerMapper
{
  public constructor(props: { context: ISalesContext }) {
    super(props);
  }

  protected toDomainMappingImpl(source: Dealer_Model, params: any): Dealer {
    const name = this.mapsValue(source, "name", Name.create);
    const user_id = this.mapsValue(source, "user_id", UniqueID.create);
    const status = this.mapsValue(source, "status", DealerStatus.create);
    const language = this.mapsValue(source, "lang_code", Language.createFromCode);
    const currency = this.mapsValue(source, "currency_code", CurrencyData.createFromCode);
    const logo = this.mapsValue(source, "logo", DealerLogotype.create);

    const additionalInfoOrError = KeyValueMap.create([
      ["contact_information", source.contact_information],
      ["default_payment_method", source.default_payment_method],
      ["default_notes", source.default_notes],
      ["default_legal_terms", source.default_legal_terms],
      ["default_quote_validity", source.default_quote_validity],
      ["default_tax", source.default_tax],
    ]);

    const props: IDealerProps = {
      user_id,
      //logo: "",
      name,
      status,
      language,
      currency,
      additionalInfo: additionalInfoOrError.object,
      logo,
    };

    const id = this.mapsValue(source, "id", UniqueID.create);
    const dealerOrError = Dealer.create(props, id);

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

    return dealerOrError.object;
  }

  protected toPersistenceMappingImpl(source: Dealer, params?: MapperParamsType | undefined) {
    return {
      id: source.id.toPrimitive(),
      user_id: source.user_id.toPrimitive(),
      //id_contact: undefined,
      currency_code: source.currency.toPrimitive(),
      //logo: "",
      name: source.name.toPrimitive(),
      status: source.status.toPrimitive(),
      lang_code: source.language.toPrimitive(),
      contact_information: source.additionalInfo.get("contact_information")?.toString() ?? "",
      default_payment_method: source.additionalInfo.get("default_payment_method")?.toString() ?? "",
      default_notes: source.additionalInfo.get("default_notes")?.toString() ?? "",
      default_legal_terms: source.additionalInfo.get("default_legal_terms")?.toString() ?? "",
      default_quote_validity: source.additionalInfo.get("default_quote_validity")?.toString() ?? "",
      default_tax: Number(source.additionalInfo.get("default_tax") ?? 0),
      logo: source.logo.toPrimitive(),
    };
  }
}

export const createDealerMapper = (context: ISalesContext): IDealerMapper =>
  new DealerMapper({
    context,
  });
