module Pay
  class Webhook < Pay::ApplicationRecord
    validates :processor, presence: true
    validates :event_type, presence: true
    validates :event, presence: true

    def process!
      Pay::Webhooks.instrument type: "#{processor}.#{event_type}", event: rehydrated_event

      # Remove after successfully processing
      destroy
    end

    # Events have already been verified by the webhook, so we just store the raw data
    # Then we can rehydrate as webhook objects for each payment processor
    def rehydrated_event
      case processor
      when "braintree"
        Pay.braintree_gateway.webhook_notification.parse(event["bt_signature"], event["bt_payload"])
      when "paddle"
        to_recursive_ostruct(event)
      when "stripe"
        ::Stripe::Event.construct_from(event)
      else
        event
      end
    end

    def to_recursive_ostruct(hash)
      result = hash.each_with_object({}) do |(key, val), memo|
        memo[key] = val.is_a?(Hash) ? to_recursive_ostruct(val) : val
      end
      OpenStruct.new(result)
    end
  end
end