# frozen_string_literal: true

require_relative "expiring_lock"
require_relative "transaction"

class LowBalance
	def self.for(customer)
		return Locked.new unless customer.registered?

		ExpiringLock.new(
			"jmp_customer_low_balance-#{customer.customer_id}",
			expiry: 60 * 60 * 24 * 7
		).with(-> { Locked.new }) do
			customer.auto_top_up_amount.then do |auto_top_up_amount|
				for_auto_top_up_amount(customer, auto_top_up_amount)
			end
		end
	end

	def self.for_auto_top_up_amount(customer, auto_top_up_amount)
		if auto_top_up_amount.positive?
			AutoTopUp.new(customer, auto_top_up_amount)
		else
			customer.btc_addresses.then do |btc_addresses|
				new(customer, btc_addresses)
			end
		end
	end

	def initialize(customer, btc_addresses)
		@customer = customer
		@btc_addresses = btc_addresses
	end

	def notify!
		m = Blather::Stanza::Message.new
		m.from = CONFIG[:notify_from]
		m.body =
			"Your balance of $#{'%.4f' % @customer.balance} is low." \
			"#{btc_addresses_for_notification}"
		@customer.stanza_to(m)
	end

	def btc_addresses_for_notification
		return if @btc_addresses.empty?

		"\nYou can buy credit by sending any amount of Bitcoin to one of " \
		"these addresses:\n#{@btc_addresses.join("\n")}"
	end

	class AutoTopUp
		def initialize(customer, auto_top_up_amount)
			@customer = customer
			@auto_top_up_amount = auto_top_up_amount
			@message = Blather::Stanza::Message.new
			@message.from = CONFIG[:notify_from]
		end

		def sale
			Transaction.sale(@customer, amount: @auto_top_up_amount).then do |tx|
				tx.insert.then { tx }
			end
		end

		def notify!
			sale.then { |tx|
				@message.body =
					"Automatic top-up has charged your default " \
					"payment method and added #{tx} to your balance."
			}.catch { |e|
				@message.body =
					"Automatic top-up transaction for " \
					"$#{@auto_top_up_amount} failed: #{e.message}"
			}.then { @customer.stanza_to(@message) }
		end
	end

	class Locked
		def notify!; end
	end
end
