package de.szut.casino.deposit;

import com.stripe.exception.StripeException;
import com.stripe.model.checkout.Session;
import com.stripe.param.checkout.SessionRetrieveParams;
import de.szut.casino.security.service.EmailService;
import de.szut.casino.user.UserEntity;
import de.szut.casino.user.UserRepository;
import jakarta.mail.MessagingException;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.Optional;

@Service
public class TransactionService {
    private final TransactionRepository transactionRepository;
    private final UserRepository userRepository;
    private final EmailService emailService;

    public TransactionService(TransactionRepository transactionRepository, UserRepository userRepository, EmailService emailService) {
        this.transactionRepository = transactionRepository;
        this.userRepository = userRepository;
        this.emailService = emailService;
    }

    public void createTransaction(
            UserEntity user,
            String sessionID,
            Double amount
    ) {
        TransactionEntity transaction = new TransactionEntity();

        transaction.setUser(user);
        transaction.setSessionId(sessionID);
        transaction.setAmount(amount);

        transactionRepository.save(transaction);
    }

    public void fulfillCheckout(String sessionID) throws StripeException, MessagingException, IOException {
        SessionRetrieveParams params = SessionRetrieveParams.builder()
                .addExpand("line_items")
                .build();
        Session checkoutSession = Session.retrieve(sessionID, params, null);

        if (!"paid".equals(checkoutSession.getPaymentStatus())) {
            return;
        }

        Optional<TransactionEntity> optionalTransaction = transactionRepository.findOneBySessionID(sessionID);
        if (optionalTransaction.isEmpty()) {
            throw new RuntimeException("Transaction not found");
        }

        TransactionEntity transaction = optionalTransaction.get();
        transaction.setStatus(TransactionStatus.SUCCEEDED);

        UserEntity user = transaction.getUser();
        Long amountTotal = checkoutSession.getAmountTotal();
        if (amountTotal != null) {
            user.addBalance(BigDecimal.valueOf(amountTotal).movePointLeft(2));
        }

        userRepository.save(user);
        transactionRepository.save(transaction);
        emailService.sendDepositEmail(transaction);
    }
}
