class Closing < InvoicingRecord
  include Hashable

  has_many :closing_amounts

  def self.create_closing
    ActiveRecord::Base.transaction do
      closing_date = Time.now.end_of_day - 1.day

      closing = new(closing_date: closing_date)

      payment_lines = PaymentLine.where(hash_string: nil).where('created_at <= ?', closing_date).order(id: :asc).each do |payment_line|
        payment_line.set_hash_string
      end

      vat_amount = PaymentAmount.where(hash_string: nil, payment_id: payment_lines.pluck(:payment_id)).where.not(vat_rate: 0).order(:vat_rate).group_by(&:vat_rate).reduce(0) do |sum, (vat_rate, lines)|
        vat = lines.sum(&:vat)
        closing_amount = closing.closing_amounts.build(vat_rate: vat_rate)
        closing_amount.grand_vat_total = closing_amount.computed_grand_vat_total(vat)
        closing_amount.perpetual_vat_total = closing_amount.computed_perpetual_vat_total(vat)
        sum += vat
        sum
      end

      PaymentAmount.where(hash_string: nil).where('created_at <= ?', closing_date).order(id: :asc).each do |payment_amount|
        payment_amount.set_hash_string
      end

      amount = payment_lines.sum(&:amount)
      closing.cumulative_total = closing.computed_cumulative_total(amount)
      closing.perpetual_total = closing.computed_perpetual_total(amount)
      closing.grand_vat_total = closing.computed_grand_vat_total(vat_amount)
      closing.perpetual_vat_total = closing.computed_grand_vat_total(vat_amount)
      closing.save!
      closing.set_hash_string(true)

      closing.closing_amounts.each do |closing_amount|
        closing_amount.set_hash_string
      end
    end
  end

  def previous_closing
    self.class.order(id: :desc).find_by("YEAR(closing_date) = ?", closing_date.year) if closing_date
  end

  def computed_cumulative_total(amount)
    previous_closing&.cumulative_total.to_f + amount
  end

  def computed_perpetual_total(amount)
    self.class.last&.perpetual_total.to_f + amount
  end

  def computed_grand_vat_total(amount)
    previous_closing&.grand_vat_total.to_f + amount
  end

  def computed_perpetual_vat_total(amount)
    self.class.last&.perpetual_vat_total.to_f + amount
  end

  def computed_hash_string
    Digest::SHA2.new(256).hexdigest [
      previous_hash_string,
      closing_date&.utc&.strftime('%Y-%m-%d %H:%M:%S'),
      cumulative_total,
      perpetual_total,
      grand_vat_total,
      perpetual_vat_total,
      created_at&.utc&.strftime('%Y-%m-%d %H:%M:%S')
    ].join('/')
  end
end
