class Accounting::Subcategory < ApplicationRecord
  audited associated_with: :category

  belongs_to :category

  belongs_to :payjunction_convenience_fee, optional: true

  has_many :transaction_details, dependent: :destroy
  has_many :student_matrices, dependent: :destroy
  has_many :accounting_transactions, through: :transaction_details

  validates :name, presence: true, length: { maximum: 255 }
  validates :viewable, presence: true

  before_create :make_viewable_or_destroy

  scope :by_viewable, ->(flag) { where(viewable: true) if flag }

  scope :by_transaction_type, ->(type) do
    return unless type

    joins(transaction_details: :accounting_transaction)
      .merge(Accounting::Transaction.send("only_#{type.to_s.pluralize}"))
  end

  scope :by_open_transaction, -> do
    joins(:transaction_details).merge(Accounting::TransactionDetail.opened)
  end

  scope :with_transactions_by_family, ->(family) do
    joins(:accounting_transactions).where(accounting_transactions: { family_id: family })
  end

  scope :with_recent_activity, ->(flag) do
    return unless flag

    joins(:accounting_transactions)
      .where(accounting_transactions: { closed: false })
      .or(
        joins(:accounting_transactions)
        .where(accounting_transactions: { posted_on: (Time.zone.today - 90)..(Time.zone.today) })
      )
      .distinct
  end

  def self.ordered
    includes(:category)
      .order('accounting_categories.name ASC')
      .order(:name)
  end

  def child_associations?
    transaction_details.any? || student_matrices.any? || !!payjunction_convenience_fee
  end

  private
    def make_viewable_or_destroy
      non_viewable = category.subcategories.find_by(viewable: false)
      return unless non_viewable

      if non_viewable.child_associations?
        non_viewable.update(viewable: true)
      else
        non_viewable.destroy
      end
    end
end
