# frozen_string_literal: true require "bigdecimal" require "forwardable" require "relative_time" require "value_semantics/monkey_patched" require_relative "proxied_jid" require_relative "customer_plan" require_relative "form_template" require_relative "promise_hash" class PlanInfo extend Forwardable def_delegators :plan, :expires_at, :auto_top_up_amount def self.for(plan) return EMPromise.resolve(NoPlan.new) unless plan&.plan_name plan.activation_date.then do |adate| new(plan: plan, start_date: adate) end end class NoPlan def template FormTemplate.new("") end def admin_template FormTemplate.new("") end def status "Transitional" end end value_semantics do plan CustomerPlan start_date Time end def template FormTemplate.for("plan_info", plan_info: self) end def admin_template FormTemplate.for("admin_plan_info", plan_info: self) end def monthly_price "$%.4f / month" % plan.monthly_price end def relative_start_date RelativeTime.in_words(start_date) end def formatted_start_date start_date.strftime("%Y-%m-%d %H:%M:%S") end def currency (plan.currency || "No Currency").to_s end def status plan.active? ? "Active" : "Expired" end end class CustomerInfo value_semantics do plan_info Either(PlanInfo, PlanInfo::NoPlan) tel Either(String, nil) balance BigDecimal cnam Either(String, nil) end def self.for(customer, plan) PromiseHash.all( plan_info: PlanInfo.for(plan), tel: customer.registered? ? customer.registered?.phone : nil, balance: customer.balance, cnam: customer.tndetails.dig(:features, :lidb, :subscriber_information) ).then(&method(:new)) end def form FormTemplate.render("customer_info", info: self) end end class AdminInfo value_semantics do jid ProxiedJID, coerce: ProxiedJID.method(:new) customer_id String fwd Either(CustomerFwd, nil) info CustomerInfo api API call_info String end def self.for(customer, plan) PromiseHash.all( jid: customer.jid, customer_id: customer.customer_id, fwd: customer.fwd, info: CustomerInfo.for(customer, plan), api: customer.api, call_info: call_info(customer) ).then(&method(:new)) end class FakeLowBalance def self.for(_) self end def self.notify! EMPromise.resolve(0) end end def self.call_info(customer) if customer.registered? CallAttemptRepo.new .find_outbound(customer, "+1", call_id: "", low_balance: FakeLowBalance) .then(&:to_s) else EMPromise.resolve("No calling") end end def form FormTemplate.render("admin_info", admin_info: self) end def tel_link [ "https://dashboard.bandwidth.com/portal/r/a", CONFIG[:creds][:account], "numbers/details", info.tel.gsub(/\A\+1/, "") ].join("/") end end