# frozen_string_literal: true require "value_semantics/monkey_patched" class CallAttempt EXPENSIVE_ROUTE = { "usd_beta_unlimited-v20210223" => 0.9, "cad_beta_unlimited-v20210223" => 1.1 }.freeze def self.for(customer, other_tel, rate, usage, direction:, **kwargs) included_credit = [customer.minute_limit.to_d - usage, 0].max if !rate || rate >= EXPENSIVE_ROUTE.fetch(customer.plan_name, 0.1) Unsupported.new(direction: direction) elsif included_credit + customer.balance < rate * 10 NoBalance.new(balance: customer.balance, direction: direction) else for_ask_or_go( customer, other_tel, rate, usage, direction: direction, **kwargs ) end end def self.for_ask_or_go(customer, otel, rate, usage, digits: nil, **kwargs) can_use = customer.minute_limit.to_d + customer.monthly_overage_limit if digits != "1" && can_use - usage < rate * 10 AtLimit.new(**kwargs.slice(:direction, :call_id)) else new(from: customer.registered?.phone, to: otel, **kwargs) end end value_semantics do from(/\A\+\d+\Z/) to(/\A\+\d+\Z/) call_id String direction Either(:inbound, :outbound) end def to_render ["#{direction}/connect", { locals: to_h }] end def create_call(fwd, *args, &block) fwd.create_call(*args, &block) end class Unsupported value_semantics do direction Either(:inbound, :outbound) end def to_render ["#{direction}/unsupported"] end def create_call(*); end end class NoBalance value_semantics do balance Numeric direction Either(:inbound, :outbound) end def to_render ["#{direction}/no_balance", { locals: to_h }] end def create_call(*); end end class AtLimit value_semantics do call_id String direction Either(:inbound, :outbound) end def to_render ["#{direction}/at_limit", { locals: to_h }] end def create_call(fwd, *args, &block) fwd.create_call(*args, &block) end end end