class Admin::Accounting::Billing::ScheduledController < Admin::Accounting::Controller
  include DateRangeHelper

  def index
    days = transaction_days
      .by_date_range(date_range(params[:dates]))
      .by_category(params[:subcategory_id])
      .includes(
        :processed_transactions,
        detail: [
          { template_transaction: :template },
          { subcategory: :category },
          { plan_transactions: { plan: :student } }
        ]
      )

    render_success :ok, json: days.map { |d| scheduled_props(d) }
  end

  def batch_create
    processed_transactions = []

    processing_days.each do |day|
      detail = day.detail

      detail.plan_transactions.each do |plan|
        next if plan.processed_transactions.find { |t| t.transaction_day_id == day.id }

        transaction = build_transaction(detail, plan.student, day.date)
        transaction.build_billing_processed_transaction(plan_transaction: plan, day: day)
        processed_transactions += plan.student.accounting_transaction_matrix(transaction)
      end
    end

    if transactional_save(processed_transactions)
      allocate_funds(processed_transactions)
      render_success :ok, message: 'Transactions processed'
    else
      render_error :unprocessable_entity
    end
  end

  private
    def transaction_days
      current_school.billing_transaction_days.distinct
    end

    def processing_days
      transaction_days
        .where(id: params[:day_ids])
        .includes(
          detail: [
            :subcategory,
            {
              plan_transactions: [
                :processed_transactions,
                {
                  plan: {
                    student: [:family, :accounting_student_matrices]
                  }
                }
              ]
            }
          ]
        )
    end

    def build_transaction(detail, student, date)
      family = student.family
      transaction = detail.charge ? family.accounting_increases : family.accounting_decreases
      transaction.build(
        student: student,
        subcategory: detail.subcategory,
        memo: detail.memo,
        amount: detail.amount,
        action: detail.charge ? :charge : :credit,
        posted_on: date
      )
    end

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

    def scheduled_props(day)
      detail = day.detail
      subcategory = detail.subcategory
      plan_transactions = detail.plan_transactions
      is_template = !!detail.template_transaction

      {}.tap do |props|
        props[:id] = day.id
        props[:date] = day.date
        props[:subcategory_id] = detail.subcategory_id
        props[:subcategory_name] = subcategory.decorate.title
        props[:memo] = detail.memo
        props[:template_name] = detail.template_transaction&.template&.name
        if is_template
          props[:student_name] = 'Multiple Students'
        else
          props[:student_id] = plan_transactions.first.plan.student_id
          props[:student_name] = plan_transactions.first.plan.student.full_name(:reverse)
        end
        props[:amount] = detail.amount.to_f
        props[:processed] = day.processed_transactions.size
        props[:total] = plan_transactions.size
      end
    end
end
