# frozen_string_literal: true

require "value_semantics/monkey_patched"

require_relative "customer"
require_relative "form_template"
require_relative "form_to_h"
require_relative "reachability_repo"

class ReachabilityForm
	using FormToH

	REPOS = {
		"sms" => ReachabilityRepo::SMS,
		"voice" => ReachabilityRepo::Voice
	}.freeze

	class Result
		value_semantics do
			repo ReachabilityRepo
			target Customer
			sender Either(String, nil)
		end

		def prompt
			return unless sender

			Blather::Stanza::Message.new.tap do |m|
				m.body = "/#{repo.type}"
				# stanza_from will fix domain
				m.to = Blather::JID.new("#{sender}@sgx-jmp")
			end
		end
	end

	def initialize(customer_repo)
		@customer_repo = customer_repo
	end

	def render
		FormTemplate.render("reachability")
	end

	def render_result(count)
		FormTemplate.render("reachability_result", count: count)
	end

	def parse(form)
		params = form.to_h
		tel = cleanup_tel(params["tel"])

		sender = cleanup_sender(params["reachability_tel"])

		repo = REPOS[params["type"]]
		raise "Type is invalid" unless repo

		find_target(tel).then { |target|
			Result.new(target: target, repo: repo.new, sender: sender)
		}
	end

protected

	def find_target(tel)
		@customer_repo.find_by_tel(tel)
	end

	def cleanup_sender(str)
		return nil unless str

		str = str.strip
		return nil if str.empty?

		unless CONFIG[:reachability_senders].include?(str)
			raise "Sender not in whitelist"
		end

		str
	end

	def cleanup_tel(str)
		"+1#{str.gsub(/\A\+?1?/, '')}"
	end
end
