# frozen_string_literal: true

module Accounts
  class PrevalidateEmail < Action
    class EmailableError < StandardError; end

    HTTP_TIMEOUT = 10.seconds
    API_KEY = ENV.fetch('EMAILABLE_API_KEY', nil)
    URL = 'https://api.emailable.com/v1/verify'
    URL_TEMPLATE = Addressable::Template.new("#{URL}?api_key=#{API_KEY}{&email}").freeze

    parameter :email, required: true

    def call
      { result:, reason: }
    end

    private

    def reason
      ActiveSupport::StringInquirer.new(response_data['reason'] || '')
    end

    def result
      ActiveSupport::StringInquirer.new(response_data['state'] || '')
    end

    def response_data
      return @response_data if @response_data
      return @response_data = default_unknown_response_for('unauthorized') unless API_KEY

      response = HTTP.timeout(HTTP_TIMEOUT.to_i).get(url)

      if response.status == 200
        @response_data = response.parse
      else
        Sentry.capture_exception(EmailableError.new, extra: {
          response_status: response.status,
          response_data: response.parse
        })
        @response_data = default_unknown_response_for('bad_gateway')
      end
    rescue HTTP::TimeoutError => e
      Sentry.capture_exception(e)
      @response_data = default_unknown_response_for('timeout')
    end

    def default_unknown_response_for(reason)
      {
        'state' => 'unknown',
        'reason' => reason,
        'email' => email
      }
    end

    def url
      @url ||= URL_TEMPLATE.expand(email:)
    end
  end
end
