module WolfCore::FkmOperations

def create_foreign_key(tenant:, source:, source_id:, destination:, destination_id:)

def create_foreign_key(tenant:, source:, source_id:, destination:, destination_id:)
  raise_service_error({ message: "tenant is required to create a foreign key", tenant: tenant }) if tenant.blank?
  raise_service_error({ message: "source is required to create a foreign key", source: source }) if source.blank?
  if source_id.blank?
    raise_service_error({ message: "source_id is required to create a foreign key",
                          source_id: source_id })
  end
  if destination.blank?
    raise_service_error({ message: "destination is required to create a foreign key",
                          destination: destination })
  end
  if destination_id.blank?
    raise_service_error({ message: "destination_id is required to create a foreign key",
                          destination_id: destination_id })
  end
  response = http_post(
    url: "#{ENV["FKM_URL"]}/Prod/create",
    body: {
      tenant: tenant,
      source: source,
      source_id: source_id,
      destination: destination,
      destination_id: destination_id
    }
  )
  response = parse_http_response(response)
  log_object response, title: "create_foreign_key response is"
  validate_http_response(response: response, message: "Error creating foreign key")
  parse_http_response(response).body
end

def find_or_create_foreign_key(tenant:, source:, source_id:, destination:, destination_id:)

def find_or_create_foreign_key(tenant:, source:, source_id:, destination:, destination_id:)
  found_destination_id = get_foreign_key_destination_id(
    tenant: tenant, source: source, source_id: source_id,
    destination: destination
  )
  log_object "find_or_create_foreign_key found_destination_id is #{found_destination_id}"
  return Result.success(data: { operation: :find }) if found_destination_id.present?
  create_foreign_key(
    tenant: tenant, source: source, source_id: source_id,
    destination: destination, destination_id: destination_id
  )
  Result.success(data: { operation: :create })
end

def get_foreign_key_by_destination(tenant:, source:, source_id:, destination:)

def get_foreign_key_by_destination(tenant:, source:, source_id:, destination:)
  foreign_keys = get_foreign_keys(tenant: tenant, source: source, source_id: source_id)
  foreign_keys.find { |fk| fk["destination"] == destination }
end

def get_foreign_key_destination_id(tenant:, source:, source_id:, destination:)

def get_foreign_key_destination_id(tenant:, source:, source_id:, destination:)
  foreign_key = get_foreign_key_by_destination(
    tenant: tenant, source: source, source_id: source_id,
    destination: destination
  )
  foreign_key&.dig("destination_id")
end

def get_foreign_keys(tenant:, source:, source_id:)

def get_foreign_keys(tenant:, source:, source_id:)
  response = http_get(
    url: "#{ENV["FKM_URL"]}/Prod/lookup?tenant=#{tenant}&source=#{source}&source_id=#{source_id}"
  )
  response = parse_http_response(response)
  log_object response, title: "get_foreign_keys response is"
  validate_http_response(response: response, message: "Error getting foreign keys")
  response.body
end

def get_foreign_keys_by_destination(tenant:, destination:, destination_id:)

def get_foreign_keys_by_destination(tenant:, destination:, destination_id:)
  response = http_get(
    url: "#{ENV["FKM_URL"]}/Prod/lookup?tenant=#{tenant}&destination=#{destination}&destination_id=#{destination_id}"
  )
  response = parse_http_response(response)
  log_object response, title: "get_foreign_keys_by_destination response is"
  validate_http_response(response: response, message: "Error getting foreign keys by destination id")
  response.body
end

def update_foreign_key(tenant:, auth_token:, uuid:, source: nil, source_id: nil, destination: nil,

def update_foreign_key(tenant:, auth_token:, uuid:, source: nil, source_id: nil, destination: nil,
                       destination_id: nil)
  raise_service_error({ message: "tenant is required to update a foreign key", tenant: tenant }) if tenant.blank?
  if auth_token.blank?
    raise_service_error({ message: "auth_token is required to update a foreign key",
                          auth_token: auth_token })
  end
  raise_service_error({ message: "uuid is required to update a foreign key", uuid: uuid }) if uuid.blank?
  fields_to_update = {
    source: source,
    source_id: source_id,
    destination: destination,
    destination_id: destination_id
  }.compact
  if fields_to_update.blank?
    raise_service_error({ message: "At least one field to update is required to update a foreign key",
                          source: source })
  end
  body = {
    tenant: tenant,
    authentication_token: auth_token,
    uuid: uuid
  }.merge(fields_to_update)
  log_object body, title: "update_foreign_key body is"
  response = safe_http_put(
    url: "#{ENV["FKM_URL"]}/Prod/update",
    body: body,
    title: "update_foreign_key response is",
    error_message: "Error updating foreign key"
  )
  response.body
end

def upsert_foreign_key(tenant:, auth_token:, source:, source_id:, destination:, destination_id:)

def upsert_foreign_key(tenant:, auth_token:, source:, source_id:, destination:, destination_id:)
  foreign_key = get_foreign_key_by_destination(
    tenant: tenant, source: source, source_id: source_id,
    destination: destination
  )
  if foreign_key.present?
    update_foreign_key(
      tenant: tenant, auth_token: auth_token, uuid: foreign_key["uuid"],
      source: source, source_id: source_id,
      destination: destination, destination_id: destination_id
    )
  else
    create_foreign_key(
      tenant: tenant, source: source, source_id: source_id,
      destination: destination, destination_id: destination_id
    )
  end
end