class Pdf::Accounting::TransactionAgingService < Pdf::NewApplicationService
  def initialize(school, type)
    @school = school
    @by_family = type == 'family'
  end

  private
    def configuration
      {}.tap do |config|
        config[:margin] = { top: 10, bottom: 20 }
      end
    end

    def body
      ActionController::Base.new.render_to_string(
        partial: 'pdf/accounting/transaction_aging.html.haml',
        locals: {
          school: @school,
          amounts: set_totals,
          totals: @totals,
          label: @by_family ? 'Family' : 'Category'
        }
      )
    end

    def set_totals
      @totals ||= { 30 => 0, 60 => 0, 90 => 0, 91 => 0, outstanding: 0 }

      objects = @by_family ? families : subcategories
      data = objects.map do |object|
        title = @by_family ? object.name : object.decorate.title
        [object.id, @totals.merge(title: title)]
      end.to_h

      transactions.each do |transaction|
        days = (transaction.posted_on..Date.current).count
        key = @by_family ? transaction.family_id : transaction.subcategories.first.id

        day = if days <= 30
          30
        elsif days <= 60
          60
        elsif days <= 90
          90
        else
          91
        end

        balance = transaction.balance

        data[key][day] += balance
        data[key][:outstanding] += balance

        @totals[day] += balance
        @totals[:outstanding] += balance
      end

      data.values
    end

    def transactions
      @transactions ||= @school.accounting_increases
        .includes(transaction_details: :increase_allocations)
        .not_closed

      @by_family ? @transactions : @transactions.includes(:subcategories)
    end

    def subcategories
      @school.accounting_subcategories.includes(:category).by_open_transaction.ordered
    end

    def families
      @school.families.with_outstanding_balance(true).by_transaction_type(:increase).ordered
    end
end
