module Payments
  class PurchaseProfile < Payments::Base
    self.primary_attribute = :id

    attributes :id,
               :state,
               :payment_provider,
               :ext_subscription_id,
               :ext_purchaser_id,
               :ticket_id,
               :purchaser_id,
               :purchaser_name,
               :purchaser_email,
               :created_on,
               :updated_on,
               :will_renew,
               :purchase_datetime,
               :cancel_datetime,
               :do_not_renew_datetime,
               :expires_on,
               :is_paying,
               :is_recurring,
               :last_payment_date,
               :is_test,
               :paid_on,
               :is_refundable,
               :is_expired,
               :is_fully_discounted,
               :is_gift

    STATES = [:active, :cancelled, :inactive, :migrated_v2].freeze
    PAYMENT_PROVIDERS = [:recurly, :xsolla_v3, :zuora, :paypal, :paypal_rt, :free_coupons, :samus, :admin, :test].freeze
    CSV_HEADERS = {
      id: "Id",
      purchaser_id: "Purchaser Id",
      purchaser_name: "Purchaser Name",
      purchaser_email: "Purchaser Email",
      ticket_id: "Ticket Id",
      ext_purchaser_id: "Ext Purchaser",
      ext_subscription_id: "Ext Subscription",
      state: "State",
      payment_provider: "Payment Provider",
      will_renew: "Will Renew",
      is_recurring: "Is Recurring",
      is_paying: "Is Paying",
      is_gift: "Is Gift",
      purchase_datetime: "Purchase Datetime",
      do_not_renew_datetime: "Do Not Renew Datetime",
      cancel_datetime: "Cancel Datetime",
      updated_on: "Updated On",
      created_on: "Created On"
    }.freeze

    def self.filter(params = {})
      response = Mulan::PurchaseProfileQuery.call(params)

      if response.success? && response.body['purchase_profiles']
        res = response.body['purchase_profiles'].map do |purchase_profile|
          from_attributes(purchase_profile)
        end
        # Set a high page number since we don't know the total count
        paginate res, total_pages: 100
      else
        empty_response
      end
    end

    def self.find(id)
      return if id.blank?
      response = Mulan::PurchaseProfileQuery.call(id: id)
      if response.success? && response.body['purchase_profiles']
        purchase_profile = response.body['purchase_profiles'].first
        from_attributes(purchase_profile)
      end
    end

    def self.count_for_purchaser(purchaser_id)
      response = get "/users/#{purchaser_id}/purchase_profiles/count"
      response.success? ? response.body["count"] : 0
    end

    def self.empty_response
      paginate []
    end

    def self.cancel(id)
      params = { refund: true }
      response = put "/purchase_profiles/#{id}/cancel", body: params.to_json
      response.success?
    end

    def self.do_not_renew(id)
      (put "/purchase_profiles/#{id}/do_not_renew").success?
    end

    def created_on
      DateTime.parse(@created_on) rescue nil
    end

    def updated_on
      DateTime.parse(@updated_on) rescue nil
    end

    def purchase_datetime
      DateTime.parse(@purchase_datetime) rescue nil
    end

    def cancel_datetime
      DateTime.parse(@cancel_datetime) rescue nil
    end

    def do_not_renew_datetime
      DateTime.parse(@do_not_renew_datetime) rescue nil
    end

    def last_payment_date
      DateTime.parse(@last_payment_date) rescue nil
    end

    def expires_on
      DateTime.parse(@expires_on) rescue nil
    end

    def ticket_owner
      @ticket_owner ||= Twitch::User.find(ticket.owner_id) unless ticket.nil?
    end

    def purchaser
      @purchaser ||= Twitch::User.find(purchaser_id)
    end

    def product
      return @product unless @product.blank?
      return nil if ticket.nil?

      tp = Subscriptions::TicketProduct.find(ticket.ticket_product_id) unless ticket.nil?
      @product = tp.errors.blank? ? tp : nil
    end

    def ticket
      return @ticket unless @ticket.blank?
      @ticket = Substwirp::Subscription.get_by_purchase_profile(id)
    end

    def purchase_payments
      @purchase_payments ||= Payments::PurchasePayment.filter(purchase_profile_id: id).sort_by{ |purchase_payment| purchase_payment.received_on }.reverse
    end

    def load_associations
      return Concurrent::Future.execute{ product }, Concurrent::Future.execute{ purchaser }
    end

    def to_csv_row
      CSV_HEADERS.keys.map{ |key| self.attributes[key] }
    end
  end
end
