class Finance::PrepaidBillingStrategy < Finance::BillingStrategy

  def daily(options = {})
    now = options[:now].presence || Time.now.utc
    bill_and_charge_each(options) do |buyer|
      Rails.logger.info("Started to bill and charge of #{buyer.name} at #{now}")
      bill_expired_trials(buyer, now)

      only_on_days(now, 1) do
        bill_fixed_costs(buyer, now)
        bill_variable_costs(buyer, now - 1.month)
      end

      finalize_invoices_of(buyer, now)
      issue_invoices_of(buyer, now)

      charge_invoices(buyer, now)
    end

    only_on_days(now, 1) { notify_about_finalized_invoices }
    notify_about_expired_credit_cards(now)
  end

  def name
    'prepaid'
  end

  def description
    %q{In prepaid mode, all fixed fees and setup fees are
       billed immediately at the beginning of the month or
       at the beginning of any pro-rated billing period.
       Variable costs are always calculated at the end
       of the month.
    }
  end

  # Differs from Postpaid #bill_variable_costs just by the invoice
  # that is used to bill on: here it is the following month.
  #
  def bill_variable_costs(buyer, now = Time.now.utc)
    month = Month.new(now)

    info("Billing variable cost of #{buyer.org_name} at #{now}", buyer)
    buyer.contracts.find_each(batch_size: 100) do |contract|
      invoice = invoice_for(account, buyer, now + 1.month)
      contract.bill_for_variable(month, invoice)
    end
  end

  def bill_plan_change(contract, period)
    difference = contract.plan.cost_for_period(period) - contract.old_plan.cost_for_period(period)

    if difference > 0
      description = "#{contract.class.model_name.human} upgrade ('#{contract.old_plan.name}' to '#{contract.plan.name}')"
      add_cost( contract, description, period.to_s, difference)
    else
      info("Not billing anything for plan change ('#{contract.old_plan.name}' to '#{contract.plan.name}')")
    end
  end

  protected

  def invoices_to_finalize_of(buyer, now)
    provider.buyer_invoices.by_buyer(buyer).opened
  end

end
