lib/requests/payments/destinations/card.ex

defmodule Requests.Payments.Destinations.Card do
  alias Requests.Payments.Destinations.Holders.{
    CorporateAccount,
    IndividualAccount,
    GovernmentAccount
  }

  @type t :: %__MODULE__{
          account_holder: map(),
          number: String.t(),
          expiry_month: integer(),
          expiry_year: integer(),
          type: String.t()
        }

  @enforce_keys [
    :account_holder,
    :number,
    :expiry_month,
    :expiry_year,
    :type
  ]

  defstruct [
    :account_holder,
    :number,
    :expiry_month,
    :expiry_year,
    :type
  ]

  def build(params) when is_map(params) do
    %__MODULE__{
      account_holder: build_account_holder(params[:account_holder]),
      number: params[:number],
      expiry_month: params[:expiry_month],
      expiry_year: params[:expiry_year],
      type: params[:type]
    }
  end

  def build(_), do: nil

  defp build_account_holder(%{type: "individual"} = params),
    do: IndividualAccount.build(params)

  defp build_account_holder(%{type: "corporate"} = params),
    do: CorporateAccount.build(params)

  defp build_account_holder(%{type: "government"} = params),
    do: GovernmentAccount.build(params)

  defp build_account_holder(_), do: nil
end