class Admin::Accounting::StudentsController < Admin::Accounting::Controller
  include CacheHelper

  def index
    @students = current_school.students
      .current_status(current_school, params[:status]&.to_sym)
      .by_family_ids(params[:family_ids])
      .with_outstanding_balance(params[:balance]&.to_bool)
      .order_by_current(params[:order_by_current], current_school_year.id)
      .ordered
      .distinct
      .to_a

    render_success :ok, json: @students.map { |s| student_props(s) }
  end

  def show
    render_success :ok, json: student_props(student).merge(subcategories: breakdown)
  end

  def statement
    Reporting::Accounting::StudentStatementJob.perform_async(
      current_school.id,
      current_user.id,
      id: params[:id],
      dates: params[:dates],
      category_ids: params[:category_ids],
      statement_type: params[:statement_type],
      family_id: params[:family_id]
    )
    render_success :ok
  end

  private
    def student
      @student ||= current_school.students.find_by(id: params[:id])
    end

    def breakdown
      current_school.accounting_subcategories.map do |subcategory|
        {}.tap do |props|
          props[:name] = subcategory.decorate.title
          props[:total] = sprintf('%.2f', student.computed_balance(subcategory.id))
          student.families.each_with_index do |family, index|
            props["family_#{index + 1}"] =
              sprintf('%.2f', family.computed_balance(subcategory.id, student.id))
          end
        end
      end
    end

    def permissions
      if [:index, :show, :statement].include?(action_name.to_sym)
        ['read', 'write', 'manage']
      else
        ['write', 'manage']
      end
    end

    def current_student_ids
      @current_student_ids ||= current_school_year.school_year_students
        .where(student: student || @students, current: true)
        .pluck(:student_id)
    end

    def student_balances(student)
      load_cache("student/#{student.id}/balance", false) do
        {
          outstanding: student.outstanding_balance,
          unallocated: student.unallocated_balance
        }.to_json
      end
    end

    def student_props(student)
      balances = student_balances(student)
      {
        id: student.id,
        family_id: student.family_id,
        first_name: student.first_name,
        last_name: student.last_name,
        full_name: student.full_name,
        grade: student.grade,
        grade_label: grade_levels[student.grade],
        graduated: student.graduated,
        status: current_student_ids.include?(student.id),
        outstanding: sprintf('%.2f', balances['outstanding']),
        unallocated: sprintf('%.2f', balances['unallocated'])
      }
    end
end
