package ru.soune.nocopy.service.referral; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; import ru.soune.Referral; import ru.soune.ReferralInvitee; import ru.soune.ReferralRepo; import ru.soune.nocopy.entity.user.User; import ru.soune.nocopy.repository.ReferralJpaRepository; import ru.soune.nocopy.repository.UserRepository; import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.List; import java.util.UUID; @Repository @RequiredArgsConstructor @Slf4j @Transactional public class ReferralRepoImpl implements ReferralRepo { private final ReferralJpaRepository referralRepository; private final UserRepository userRepository; @Override public @NotNull String getUserReferralLink(long userId) { ru.soune.nocopy.entity.referral.Referral referral = referralRepository.findByUserId(userId); if (referral != null && referral.getReferralLink() != null && !referral.getReferralLink().isEmpty()) { return referral.getReferralLink(); } String newLink = "ref-" + userId + "-" + UUID.randomUUID().toString().substring(0, 8); if (referral == null) { referral = new ru.soune.nocopy.entity.referral.Referral(); referral.setUserId(userId); referral.setLevelId("bronze"); referral.setActive(false); } referral.setReferralLink(newLink); referralRepository.save(referral); return newLink; } @Override public @NotNull Long getUserIdByLink(@NotNull String link) { ru.soune.nocopy.entity.referral.Referral referral = referralRepository.findByReferralLink(link); return referral != null ? referral.getUserId() : 0L; } @Override public @Nullable Long getInviterIdForUser(long userId) { ru.soune.nocopy.entity.referral.Referral referral = referralRepository.findByUserId(userId); return referral != null ? referral.getInviterId() : 0L; } @Override public @NotNull String getReferralLevelForUser(long userId) { ru.soune.nocopy.entity.referral.Referral referral = referralRepository.findByUserId(userId); return referral != null ? referral.getLevelId() : ""; } @Override public @NotNull Referral getReferralByUserId(long userId) { ru.soune.nocopy.entity.referral.Referral entity = referralRepository.findByUserId(userId); if (entity == null) { return createDefaultReferral(userId); } return new Referral() { @Override public long getUserId() { return entity.getUserId(); } @Override public String getReferralLink() { return entity.getReferralLink(); } @Override public Long getInviter() { return entity.getInviterId() != null ? entity.getInviterId() : 0L; } @Override public String getCurrentLevel() { return entity.getLevelId(); } @Override public int getTotalIncome() { return entity.getTotalIncome(); } @Override public int getAvailableIncome() { Integer holdBalance = entity.getHoldBalance(); return entity.getTotalIncome() - (holdBalance != null ? holdBalance : 0); } @Override public int getHoldBalance() { Integer holdBalance = entity.getHoldBalance(); return holdBalance != null ? holdBalance : 0; } @Override public boolean getActive() { return entity.isActive(); } }; } private Referral createDefaultReferral(long userId) { return new Referral() { @Override public long getUserId() { return userId; } @Override public String getReferralLink() { return ""; } @Override public Long getInviter() { return 0L; } @Override public String getCurrentLevel() { return "bronze"; } @Override public int getTotalIncome() { return 0; } @Override public int getAvailableIncome() { return 0; } @Override public int getHoldBalance() { return 0; } @Override public boolean getActive() { return false; } }; } @Override public @NotNull List getReferralInvitees(long userId, int pageSize, int pageNumber) { Pageable pageable = PageRequest.of(pageNumber, pageSize); List referrals = referralRepository.findByInviterId(userId, pageable); List result = new ArrayList<>(); for (ru.soune.nocopy.entity.referral.Referral referral : referrals) { User user = userRepository.findById(referral.getUserId()).orElse(null); String email = user != null ? user.getEmail() : ""; boolean isActive = referral.isActive(); String regDate = referral.getCreatedAt() != null ? referral.getCreatedAt().toString() : ""; try { Constructor constructor = ReferralInvitee.class.getDeclaredConstructor( String.class, boolean.class, String.class ); ReferralInvitee invitee = constructor.newInstance(email, isActive, regDate); result.add(invitee); } catch (Exception e) { e.printStackTrace(); } } return result; } @Override public void createReferralEntity(@NotNull Referral entity) { ru.soune.nocopy.entity.referral.Referral referral = new ru.soune.nocopy.entity.referral.Referral(); referral.setUserId(entity.getUserId()); referral.setReferralLink(entity.getReferralLink()); referral.setInviterId(entity.getInviter()); referral.setLevelId(entity.getCurrentLevel()); referral.setTotalIncome(entity.getTotalIncome()); referral.setHoldBalance(entity.getHoldBalance()); referral.setActive(entity.getActive()); referralRepository.save(referral); } @Override public void increaseIncome(long userId, int transferAmount) { referralRepository.increaseIncome(userId, transferAmount); } @Override public boolean activateUser(long userId) { try { referralRepository.activateUser(userId); return true; } catch (Exception e) { return false; } } @Override public int getActiveInviteeForUser(long userId) { return referralRepository.countActiveInvitees(userId); } @Override public int getTotalInviteeForUser(long userId) { return referralRepository.countTotalInvitees(userId); } @Override public void upgradeReferralLevelForUser(long userId, @NotNull String newLevelId) { referralRepository.updateLevel(userId, newLevelId); } }