class Object
  def metaclass
    class << self; self; end
  end
end

module Edools
  class Payment < Edools::Base
    # Basic
    attr_accessor :id, :amount

    # Gateway
    attr_accessor :gateway_fees, :gateway_category

    # Payment
    attr_accessor :type, :status, :translated_type, :translated_status

    # Dates
    attr_reader :created_at, :updated_at

    # Other
    attr_reader :customer, :student, :order

    def initialize json
      @json = json

      [:id, :amount, :gateway_fees, :gateway_category, :type, :status, :translated_type, :translated_status, :created_at, :updated_at, :customer, :student, :order].each do |attr|

        if attr == :student and json[attr.to_s].blank?
          self.send("#{attr}=".to_sym, json['customer'])
        else
          self.send("#{attr}=".to_sym, json[attr.to_s])
        end
      end
    end

    def created_at= value
      if value.is_a? String
        value = Time.zone.parse(value)
      end
      @created_at = value
    end

    def updated_at= value
      if value.is_a? String
        value = Time.zone.parse(value)
      end
      @updated_at = value
    end

    def customer= value
      @customer = Edools::Customer.new value
    end

    def student= value
      @student = Edools::Student.new value
    end

    def order= value
      @order = Edools::Order.new value
    end

    def self.waiting_statuses
      ['initiated', 'under_analysis', 'payment_slip_impressed']
    end

    def self.paid_statuses
      ['authorized', 'done']
    end

    def self.canceled_statuses
      ['canceled', 'reversed']
    end

    def self.statuses
      self.waiting_statuses + self.paid_statuses + self.canceled_statuses
    end

    [:waiting, :paid, :canceled].each do |attr|
      define_method "#{attr}?".to_sym do
        self.class.send("#{attr}_statuses".to_sym).include? self.status
      end

      metaclass.instance_eval do
        define_method "all_#{attr}".to_sym do
          self.all self.send("#{attr}_params".to_sym)
        end

        define_method "#{attr}_params".to_sym do
          { status: self.send("#{attr}_statuses".to_sym).join(',') }
        end

        define_method "all_#{attr}_after".to_sym do |time|
          if time.nil?
            self.send("all_#{attr}".to_sym)
          else
            self.all self.after_params(time).merge(self.send("#{attr}_params".to_sym))
          end
        end
      end
    end

    def self.all_after time
      if time.nil?
        self.all
      else
        self.all self.after_params(time)
      end
    end

    def self.after_params time
      { start_date: Edools.time_to_query(time) }
    end

    def self.path
      "payments"
    end

    def self.type
      :ecommerce
    end
  end
end
