package ru.soune

class ReferralService(
    private val referralLevelProvider: ReferralLevelProvider,
    private val referralRepo: ReferralRepo,
) {

    fun onRegister(userId: Long, inviterReferralLink: String?) {
        val initialReferralLevel = referralLevelProvider.getInitialReferralLevelId()
        val referralLink = referralRepo.getUserReferralLink(userId)
        val inviter = inviterReferralLink?.let(referralRepo::getUserIdByLink)

        val referral = object : Referral {
            override val userId = userId
            override val referralLink = referralLink
            override val inviter = inviter
            override val currentLevel = initialReferralLevel
            override val totalIncome = 0
            override val availableIncome = 0
            override val holdBalance: Int = 0
            override val spentBalance: Int = 0
            override val active: Boolean = false
        }

        referralRepo.createReferralEntity(referral)
    }

    fun onUserAccountRefill(userId: Long, transferAmount: Int) {
        val wasActivated = referralRepo.activateUser(userId)
        val inviterId = referralRepo.getInviterIdForUser(userId) ?: return
        val currentInviterLevel = referralRepo.getReferralLevelForUser(inviterId)
            .let { referralLevelProvider.getReferralLevelById(it) }
        val reward = transferAmount * currentInviterLevel.share / 100

        referralRepo.increaseIncome(inviterId, reward)

        if (!wasActivated) return

        val currentCount = referralRepo.getActiveInviteeForUser(inviterId)
        val nextLevel = currentInviterLevel.next

        if (currentCount + 1 > currentInviterLevel.maxInvitee && nextLevel != null) {
            referralRepo.upgradeReferralLevelForUser(inviterId, nextLevel)
        }
    }

    fun getReferralLevels(): List<ReferralLevel> =
        referralLevelProvider.getAvailableReferralLevels()


    fun getReferralLevelForUser(userId: Long): ReferralLevel =
        referralRepo.getReferralLevelForUser(userId)
            .let { referralLevelProvider.getReferralLevelById(it) }

    fun getReferralStatForUser(userId: Long): ReferralStat {
        var referral = referralRepo.getReferralByUserId(userId)
        return ReferralStat(
            totalInvitee = referralRepo.getTotalInviteeForUser(userId),
            activeInvitee = referralRepo.getActiveInviteeForUser(userId),
            totalIncome = referral.totalIncome,
            availableIncome = referral.availableIncome,
            holdBalance = referral.holdBalance,
            referralLink = referral.referralLink,
            spentBalance = referral.spentBalance,
        )
    }

    fun getInviteeForUser(userId: Long, pageSize: Int, pageNumber: Int): List<ReferralInvitee> =
        referralRepo.getReferralInvitees(userId, pageSize, pageNumber)
}