# frozen_string_literal: true

require "multibases"
require "securerandom"

require_relative "customer"
require_relative "trust_level_repo"

class ParentCodeRepo
	def initialize(
		redis: REDIS,
		db: DB,
		trust_level_repo: TrustLevelRepo.new(redis: redis, db: db)
	)
		@redis = redis
		@db = db
		@trust_level_repo = trust_level_repo
	end

	def find(code)
		@redis.hget("jmp_parent_codes", code).then do |parent_id|
			trust_level_guard(parent_id).then { parent_id }
		end
	end

	def find_or_create(customer_id)
		trust_level_guard(customer_id).then {
			@redis.get("jmp_customer_parent_code-#{customer_id}")
		}.then do |code|
			next code if code

			code = "p#{Multibases.pack('base32upper', SecureRandom.bytes(4))}"
			EMPromise.all([
				@redis.set("jmp_customer_parent_code-#{customer_id}", code),
				@redis.hset("jmp_parent_codes", code, customer_id)
			]).then { code }
		end
	end

	def existing_subaccounts(parent_id)
		@db.query_one(<<~SQL, parent_id, default: { c: 0 }).then { |r| r[:c] }
			SELECT COUNT(*) AS c FROM customer_plans WHERE parent_customer_id=$1
		SQL
	end

	def trust_level_guard(parent_id)
		return unless parent_id

		@trust_level_repo.find(Customer.new(parent_id, "", sgx: nil)).then { |tl|
			existing_subaccounts(parent_id).then { |c| [tl, c] }
		}.then do |(tl, number_of_subaccounts)|
			unless tl.create_subaccount?(number_of_subaccounts)
				raise "Please contact support to create a subaccount"
			end
		end
	end
end
