# REFACTOR: extract to separate TrialPeriod class. https://www.pivotaltracker.com/story/show/6779593
#
module Contract::Trial
  extend ActiveSupport::Concern

  included do
    before_create :set_trial_period_expires_at, :set_setup_fee

    attr_protected :trial_period_expires_at

    scope :with_trial_period_expiring_in_days_since, ->(days,now) do
      where('DATE(cinstances.trial_period_expires_at) = DATE(?)', now + days.days)
    end

    # TODO: merge with the one above
    scope :with_trial_period_expired, ->(today) do
      where('DATE(cinstances.trial_period_expires_at) = DATE(?)', today.to_date)
    end
  end

  module ClassMethods
    # REFACTOR: extract to notifier
    def notify_about_expired_trial_periods(now = Time.now.utc)
      with_trial_period_expiring_in_days_since(10,now).each do |cinstance|
        cinstance.notify_about_expired_trial_period
      end

      with_trial_period_expired(Date.today).find_each do |cinstance|
        cinstance.notify_provider_trial_expired_today
      end
    end
  end

  def trial?
    # TODO: - can remove the non-nil condition when cinstance for
    # master has trial_period_expires_at set on factory creation (in tests)
    self.trial_period_expires_at && (Time.now.utc < self.trial_period_expires_at)
  end

  def remaining_trial_period_days
   (remaining_trial_period_seconds / 1.day).round
  end

  def remaining_trial_period_seconds
    [trial_period_expires_at - Time.now.utc, 0].max
  end

  # REFACTOR: extract to notifier
  def notify_about_expired_trial_period
    if paid_and_trial? && !provider_account.provider_can_use?(:new_notification_system)
      messenger.expired_trial_period_notification(self).deliver
    end
  end

  def notify_provider_trial_expired_today
    notify_observers(:expired_trial_period) if paid_and_trial?
  end

  def set_trial_period_expires_at
    self.trial_period_expires_at = Time.now.utc + (plan.trial_period_days || 0).days
  end

  def set_setup_fee
    self.setup_fee = (plan.setup_fee || 0)
  end

  private

  def paid_and_trial?
    plan.paid? && plan.trial_period_days && !plan.trial_period_days.zero?
  end
end
