class PhotographerClosing < InvoicingRecord
  include Hashable

  has_many :photographer_closing_amounts

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

      photographer_closing = new(closing_date: closing_date)

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

      vat_amount = PhotographerPaymentAmount.where(hash_string: nil, photographer_payment_id: photographer_payment_lines.pluck(:photographer_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)
        photographer_closing_amount = photographer_closing.photographer_closing_amounts.build(vat_rate: vat_rate)
        photographer_closing_amount.grand_vat_total = photographer_closing_amount.computed_grand_vat_total(vat)
        photographer_closing_amount.perpetual_vat_total = photographer_closing_amount.computed_perpetual_vat_total(vat)
        sum += vat
        sum
      end

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

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

      photographer_closing.photographer_closing_amounts.each do |photographer_closing_amount|
        photographer_closing_amount.set_hash_string
      end
    end
  end

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

  def computed_cumulative_total(amount)
    previous_photographer_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_photographer_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
