class Admin::Accounting::TransfersController < Admin::Accounting::Controller
  def create
    @increase_transfer = increases.build(transfer_params(subcategory))
    @decrease_transfer = decreases.build(transfer_params)
    transaction_service.build_details(subcategories, params[:distribution])
    validate_transfer_amount

    if transactional_save([@increase_transfer, @decrease_transfer])
      allocate_funds
      render_success :ok
    else
      render_error :unprocessable_entity, errors: @increase_transfer
    end
  end

  private
    def increases
      (family || current_school).accounting_increases
    end

    def decreases
      (family || current_school).accounting_decreases
    end

    def subcategories
      @subcategories ||= current_school.accounting_subcategories
    end

    def subcategory
      @subcategory ||= subcategories.find_by(id: params[:subcategory_id])
    end

    def family
      @family ||= current_school.families.find_by(id: params[:family_id])
    end

    def validate_transfer_amount
      return if @increase_transfer.amount <= family.balance(:decrease, subcategory).to_f

      @increase_transfer.add_custom_error(:base, 'Total must be less than or equal to balance')
    end

    def allocate_funds
      subcategories.each do |subcategory|
        AllocationJob.perform_now(family, subcategory, audit_user: current_user)
      end
    end

    def transaction_service
      Accounting::TransactionsService.new(family, @decrease_transfer)
    end

    def transfer_params(subcategory=nil)
      params.permit(:memo, :posted_on).merge(
        action: :transfer,
        subcategory: subcategory,
        amount: params[:total],
        tag_ids: params[:tag_ids]
      )
    end
end
