module PaymentGateways
  class Adyen12Crypt < PaymentGatewayCrypt
    CARD_DATA = %w[expiryMonth expiryYear number]

    attr_reader :gateway_client

    def initialize(user)
      super
      @gateway_client = provider.payment_gateway
    end

    # This will use ActiveMerchant::Billing::Gateway::Adyen12
    #
    # Stores a recurring contract in Adyen with the <tt>encrypted_card</tt> details
    #
    # * options may have:
    #   :ip the IP address of the current_user
    #   :recurring see https://docs.adyen.com/developers/recurring-manual#creatingarecurringcontract
    #
    # Returns a ActiveMerchant::Billing::Response
    def authorize_with_encrypted_card(encrypted_card, options = {})
      shopper_options = {
        shopperEmail: user.email,
        shopperReference: buyer_reference,
        shopperIP: options[:ip],
        recurring: 'RECURRING',
        reference: recurring_authorization_reference
      }
      gateway_client.authorize_recurring(0, encrypted_card, shopper_options)
    end

    def store_credit_card_details
      card_details = retrieve_card_details
      return false unless card_details.present?
      account.credit_card_expires_on_month = card_details['expiryMonth']
      account.credit_card_expires_on_year = card_details['expiryYear']

      account.credit_card_partial_number = card_details['number']
      account.credit_card_auth_code = buyer_reference
      account.save
    end

    # FIXME: Improvements ideas from Michal Cichra @mikz
    # InvalidResponseError = Class.new(StandardError)
    # HANDLE_INVALID_RESPONSE = -> { |key|
    #   raise InvalidResponseError, "List Recurring Details returned invalid response, missing: #{key}"
    # }
    # CarDetails = Struct.new(*CARD_DATA)

    def retrieve_card_details
      response = gateway_client.list_recurring_details(buyer_reference, {recurring: 'RECURRING'})

      if response.success?
        # TODO: consider ExtractResponseService to extract data from responses
        details = response.params['details'][0]['RecurringDetail']['card']
        #  .fetch('details', &HANDLE_INVALID_RESPONSE)
        #  .fetch(0, &HANDLE_INVALID_RESPONSE)
        #  .fetch('RecurringDetail', &HANDLE_INVALID_RESPONSE)
        #  .fetch('card', &HANDLE_INVALID_RESPONSE)

        # CardDetails.new(*CARD_DATA.map{|k| details.fetch(k, &HANDLE_INVALID_RESPONSE)})
        details.slice(*CARD_DATA)
      else
        {}
      end
    end

  end
end
