package com.fsd.hellovelo.service;

import com.fsd.hellovelo.entity.*;
import com.fsd.hellovelo.entity.Discount;
import com.fsd.hellovelo.exceptions.ResourceNotFoundException;
import com.fsd.hellovelo.repository.*;
import com.fsd.hellovelo.security.services.UserDetailsImpl;
import com.stripe.Stripe;
import com.stripe.exception.StripeException;
import com.stripe.model.*;
import com.stripe.model.Invoice;
import com.stripe.model.Subscription;
import com.stripe.param.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.util.*;

@Service
public class StripeService {

    private final UserRepository userRepository;
    private final SubscriptionRepository subscriptionRepository;
    private final DiscountRepository discountRepository;
    private final RentalRepository rentalRepository;
    private final ReferralRepository referralRepository;
    private final InvoiceRepository invoiceRepository;

    @Autowired
    public StripeService(UserRepository userRepository, SubscriptionRepository subscriptionRepository, DiscountRepository discountRepository, RentalRepository rentalRepository, ReferralRepository referralRepository, InvoiceRepository invoiceRepository) {
        this.userRepository = userRepository;
        this.subscriptionRepository = subscriptionRepository;
        this.discountRepository = discountRepository;
        this.rentalRepository = rentalRepository;
        this.referralRepository = referralRepository;
        this.invoiceRepository = invoiceRepository;
    }

    //works
    public void createCustomer(Long id) throws StripeException {
        User user = userRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("Error: User with id " + id + " not found."));
        if (user.getStripeUserId() != null) {
            return;
        }
        System.out.println("creating customer");
        Stripe.apiKey = "sk_test_51K6PnvAl7XnbPt50bAvU4L3nGTDI8nXn8a4nPhjTcbznNDfW3j7sBL1UqmL2x5yUVXygbNJ6o32Gg01juu76NkbJ00ereY9xEJ";

        CustomerCreateParams params =
                CustomerCreateParams
                        .builder()
                        .setEmail(user.getEmail())
                        .setName(user.getFirstName() + " " + user.getLastName())
                        .build();

        Customer customer = Customer.create(params);
        user.setStripeUserId(customer.getId());
        userRepository.save(user);
    }

    public Map<String, Object> createSubscription(UserDetailsImpl user, String promoCode) throws StripeException {
        Stripe.apiKey = "sk_test_51K6PnvAl7XnbPt50bAvU4L3nGTDI8nXn8a4nPhjTcbznNDfW3j7sBL1UqmL2x5yUVXygbNJ6o32Gg01juu76NkbJ00ereY9xEJ";
        Map<String, Object> responseData = new HashMap<>();
        if (user.getStripeUserId() == null) {
            createCustomer(user.getId());
        }
        User userObj = userRepository.findById(user.getId()).orElseThrow(() -> new ResourceNotFoundException("Error: User could not be found."));
        //if user has subscription - cancel or inform
        Optional<com.fsd.hellovelo.entity.Subscription> subscriptionOptional = subscriptionRepository.findFirstByUserAndTypeEqualsAndStatusNot(userObj, EType.BIKE, EPaymentStatus.CANCELED);
        if (subscriptionOptional.isPresent()) {

            //find get current payment intent
            com.fsd.hellovelo.entity.Subscription sub = subscriptionOptional.get();
            Subscription stripeSub = Subscription.retrieve(sub.getStripeSubscriptionId());
            Invoice invoice = Invoice.retrieve(stripeSub.getLatestInvoice());
            if(invoice.getStatus().equals("open")){
                PaymentIntent paymentIntent = PaymentIntent.retrieve(invoice.getPaymentIntent());
                responseData.put("subscriptionId", stripeSub.getId());
                responseData.put("clientSecret", paymentIntent.getClientSecret());
                return responseData;
            }
            //if already paid - error
            else if (!stripeSub.getStatus().equals("canceled") || !stripeSub.getStatus().equals("incomplete_expired")) {
                throw new IllegalArgumentException("Error: User already has bike subscription active.");
            } else {
                sub.setStatus(EPaymentStatus.CANCELED);
                subscriptionRepository.save(sub);
            }
        }

        com.fsd.hellovelo.entity.Discount discount = null;
        Referral referral = null;
        if(promoCode != null){
            try{
                discount = discountRepository.findByPromoCode(promoCode).orElseThrow(() -> new IllegalArgumentException("Error: Promo code is invalid! "));
                PromotionCode promotionCode = PromotionCode.retrieve(discount.getStripePromoCodeId());

                if(promotionCode == null){
                    throw new IllegalArgumentException("Error: Invalid promo code.");
                }

                if(promotionCode.getExpiresAt() != null && (promotionCode.getExpiresAt() < LocalDate.now().toEpochSecond(LocalTime.MIDNIGHT, ZoneOffset.UTC))){
                    throw new IllegalArgumentException("Error: Promo code is expired!");
                }

                if(discount.getUser() != null && discount.getUser() != userObj){
                    throw new IllegalArgumentException("Error: This promo cannot be applied to this user.");
                }
                //referral
                if(referralRepository.findFirstByReferredDiscount(discount).isPresent()){
                    referral = referralRepository.findFirstByReferredDiscount(discount).get();
                    if(!referral.getReferralEmail().equals(user.getEmail())){
                        throw new IllegalArgumentException("Error: This promo cannot be applied to this user");
                    }
                }
            }
            catch (StripeException ex){
                throw new IllegalArgumentException("Error: Promo code is invalid." + ex.getMessage());
            }
        }

        Subscription subscription = setSubscription(userObj, discount);
        if(referral != null){
            //is a referral, apply discount to referring user.
            setReferralDiscount(referral);
        }
        responseData.put("subscriptionId", subscription.getId());
        responseData.put("clientSecret", subscription.getLatestInvoiceObject().getPaymentIntentObject().getClientSecret());
        return responseData;
    }

    private void setReferralDiscount(Referral referral) throws StripeException {
        Stripe.apiKey = "sk_test_51K6PnvAl7XnbPt50bAvU4L3nGTDI8nXn8a4nPhjTcbznNDfW3j7sBL1UqmL2x5yUVXygbNJ6o32Gg01juu76NkbJ00ereY9xEJ";

        User referringUser = referral.getReferringUser();
        Discount referringDiscount =  discountRepository.findById(referral.getReferringDiscount().getId()).orElseThrow();
        if(referringUser.getStatus() == EStatus.ACTIVE && !referringDiscount.isApplied()) {

            SubscriptionUpdateParams updateParams = SubscriptionUpdateParams.builder().setPromotionCode(referringDiscount.getStripePromoCodeId()).build();
            Subscription referringSubscription = Subscription.retrieve(referringDiscount.getSubscription().getStripeSubscriptionId());
            com.fsd.hellovelo.entity.Subscription referringLocalSubscription = subscriptionRepository.findByStripeSubscriptionId(referringSubscription.getId()).orElseThrow(() -> new ResourceNotFoundException("Couldn't find subscription."));

            referringSubscription.update(updateParams);

            referringDiscount.setApplied(true);
            referringDiscount.setAppliedDate(LocalDate.now());
            discountRepository.save(referringDiscount);

//            com.fsd.hellovelo.entity.Invoice referringInvoice = invoiceRepository.findBySubscriptionAndInvoiceStatusAndUserAndDateDueAfter(referringLocalSubscription, EInvoiceStatus.CREATED, referringUser, LocalDate.now()).orElseThrow(() -> new ResourceNotFoundException("Couldn't find invoice."));
            com.fsd.hellovelo.entity.Invoice referringInvoice = invoiceRepository.findBySubscriptionAndInvoiceStatusNot(referringLocalSubscription, EInvoiceStatus.PAID).orElseThrow(() -> new ResourceNotFoundException("Can't find invoice."));
            referringInvoice.getAppliedDiscounts().add(referringDiscount);
            referringInvoice.setPaymentPrice(referringInvoice.getPaymentPrice().subtract(BigDecimal.valueOf(referringDiscount.getCoupon().getAmountOff())));
            invoiceRepository.save(referringInvoice);
        }
    }

    public Subscription setSubscription(User user, com.fsd.hellovelo.entity.Discount discount) throws StripeException {
        Stripe.apiKey = "sk_test_51K6PnvAl7XnbPt50bAvU4L3nGTDI8nXn8a4nPhjTcbznNDfW3j7sBL1UqmL2x5yUVXygbNJ6o32Gg01juu76NkbJ00ereY9xEJ";

        SubscriptionCreateParams subCreateParams = SubscriptionCreateParams
                .builder()
                .setCustomer(user.getStripeUserId())
                .addItem(
                        SubscriptionCreateParams
                                .Item.builder()
                                .setPrice("price_1KguCcAl7XnbPt50uUaJccWD")
                                .build()
                )
                .setPromotionCode(discount == null ? null : discount.getStripePromoCodeId())
                .setPaymentBehavior(SubscriptionCreateParams.PaymentBehavior.DEFAULT_INCOMPLETE)
                .addAllExpand(Arrays.asList("latest_invoice.payment_intent"))
                .build();

        Subscription subscription =
                Subscription.create(subCreateParams);
        System.out.println(subscription.getLatestInvoice() + " invoice");

        com.fsd.hellovelo.entity.Subscription localSubscription = new com.fsd.hellovelo.entity.Subscription(LocalDate.now(), EPaymentStatus.PENDING, null, null, null, user);
        localSubscription.setStripeSubscriptionId(subscription.getId());
        localSubscription.setPrice(subscription.getItems().getData().get(0).getPrice().getUnitAmountDecimal());

        subscriptionRepository.saveAndFlush(localSubscription);

        System.out.println("localSub" + localSubscription);

        com.fsd.hellovelo.entity.Invoice invoice = new com.fsd.hellovelo.entity.Invoice(user, LocalDate.now(), EPaymentStatus.PENDING, EInvoiceStatus.NOT_CREATED);
        invoice.getAppliedDiscounts().add(discount);
        invoice.setSubscription(localSubscription);
        invoice.setStripeInvoiceId(subscription.getLatestInvoice());
        invoice.setInvoiceStatus(EInvoiceStatus.CREATED);
        invoice.setPaymentPrice(subscription.getItems().getData().get(0).getPrice().getUnitAmountDecimal());
        Invoice stripeInvoice = Invoice.retrieve(subscription.getLatestInvoice());
        Instant instant = Instant.ofEpochSecond(stripeInvoice.getPeriodEnd());
        invoice.setDateDue(LocalDate.ofInstant(instant, ZoneOffset.UTC));
        invoiceRepository.saveAndFlush(invoice);
        System.out.println(invoice  + " saved invoice");

        SubscriptionItemCreateParams subParams = SubscriptionItemCreateParams
                .builder().setPrice("price_1Kh0MjAl7XnbPt501DB6BxoL")
                .setSubscription(subscription.getId()).build();

        SubscriptionItem subItem = SubscriptionItem.create(subParams);
        localSubscription.setStripeOverageItemId(subItem.getId());

        subscriptionRepository.save(localSubscription);
        System.out.println("saved sub 2 " + localSubscription);

        if(discount != null){
            discount.setApplied(true);
            discount.setAppliedDate(LocalDate.now());
            if(discount.getUser() == null){
                discount.setUser(localSubscription.getUser());
            }
            discount.setSubscription(localSubscription);

            discountRepository.save(discount);

            if(discount.getCoupon().getPercentOff() != null){
                invoice.setPaymentPrice(invoice.getPaymentPrice().subtract((discount.getCoupon().getPercentOff().divide(BigDecimal.valueOf(100))).multiply(invoice.getPaymentPrice())));
            }else{
                invoice.setPaymentPrice(invoice.getPaymentPrice().subtract(BigDecimal.valueOf(discount.getCoupon().getAmountOff())));
            }
            invoiceRepository.save(invoice);
        }
        return subscription;
    }

    public void recordInvoiceChargeAttempt(Event event, StripeObject stripeObject) throws StripeException {
        Stripe.apiKey = "sk_test_51K6PnvAl7XnbPt50bAvU4L3nGTDI8nXn8a4nPhjTcbznNDfW3j7sBL1UqmL2x5yUVXygbNJ6o32Gg01juu76NkbJ00ereY9xEJ";
        Invoice invoice = (Invoice) stripeObject;
        com.fsd.hellovelo.entity.Subscription subscription;
        switch (event.getType()) {
            case "invoice.payment_failed" -> {
                // If the payment fails or the customer does not have a valid payment method,
                // an invoice.payment_failed event is sent, the subscription becomes past_due.
                // Use this webhook to notify your user that their payment has
                // failed and to retrieve new card details.
                subscription = subscriptionRepository.findByStripeSubscriptionId(invoice.getSubscription()).orElseThrow(() -> new ResourceNotFoundException("Error: Subscription not found."));
                subscription.setStatus(EPaymentStatus.FAILED);
                subscriptionRepository.save(subscription);

                User user = subscription.getUser();
                user.setProvisionAccess(false);
                userRepository.save(user);
            }
            case "invoice.payment_succeeded" -> {
                System.out.println("in success hook");
                com.fsd.hellovelo.entity.Invoice localInvoice = invoiceRepository.findByStripeInvoiceId(invoice.getId()).orElseThrow(() -> new ResourceNotFoundException("Error: Invoice " + invoice.getId() + " not found."));
                localInvoice.setPaymentStatus(EPaymentStatus.CONFIRMED);
                localInvoice.setInvoicePdfUrl(invoice.getInvoicePdf());
                localInvoice.setInvoiceStatus(EInvoiceStatus.PAID);
                localInvoice.setPaymentPrice(BigDecimal.valueOf(invoice.getAmountDue()));
                invoiceRepository.save(localInvoice);

                Subscription subscription1 = Subscription.retrieve(invoice.getSubscription());
                if(subscription1.getStatus().equals("canceled")){
                    return;
                }

                com.fsd.hellovelo.entity.Invoice newInvoice = new com.fsd.hellovelo.entity.Invoice();
                newInvoice.setSubscription(localInvoice.getSubscription());
                newInvoice.setUser(localInvoice.getUser());
                newInvoice.setDateCreated(LocalDate.now());
                newInvoice.setPaymentStatus(EPaymentStatus.PENDING);
                newInvoice.setPaymentPrice(subscription1.getItems().getData().get(0).getPrice().getUnitAmountDecimal());
                invoiceRepository.save(newInvoice);
            }
            case "customer.subscription.deleted" -> {
                // handle subscription canceled automatically based
                // upon your subscription settings. Or if the user
                // cancels it.
                subscription = subscriptionRepository.findByStripeSubscriptionId(invoice.getSubscription()).orElseThrow(() -> new ResourceNotFoundException("Error: Subscription not found."));
                subscription.setStatus(EPaymentStatus.CANCELED);
                subscriptionRepository.save(subscription);

                User user = subscription.getUser();
                user.setProvisionAccess(false);
                userRepository.save(user);
            }
            default ->
                    // Unhandled event type
                    System.out.println("Unhandled event type: " + event.getType());
        }
    }

    //working
    public void setDefaultPayment(StripeObject stripeObject) throws StripeException {
        Stripe.apiKey = "sk_test_51K6PnvAl7XnbPt50bAvU4L3nGTDI8nXn8a4nPhjTcbznNDfW3j7sBL1UqmL2x5yUVXygbNJ6o32Gg01juu76NkbJ00ereY9xEJ";
        Invoice invoice = (Invoice) stripeObject;
        com.fsd.hellovelo.entity.Subscription sub = subscriptionRepository.findByStripeSubscriptionId(invoice.getSubscription()).orElseThrow(() -> new ResourceNotFoundException("Error: Could not find subscription."));

        if (invoice.getBillingReason().equals("subscription_create")) {
            String paymentIntentId = invoice.getPaymentIntent();
            // Retrieve the payment intent used to pay the subscription
            PaymentIntent paymentIntent = PaymentIntent.retrieve(paymentIntentId);

            // Set the default payment method
            Subscription subscription = Subscription.retrieve(invoice.getSubscription());
            SubscriptionUpdateParams params2 = SubscriptionUpdateParams
                    .builder()
                    .setDefaultPaymentMethod(paymentIntent.getPaymentMethod())
                    .build();
            Subscription updatedSubscription = subscription.update(params2);

            sub.setPaymentMethodId(paymentIntent.getPaymentMethod());
            PaymentMethod paymentMethod = PaymentMethod.retrieve(paymentIntent.getPaymentMethod());
            sub.setPaymentLast4(paymentMethod.getCard().getLast4());
            sub.setStatus(EPaymentStatus.CONFIRMED);
        }
        updateNextBillDate(sub);
        subscriptionRepository.save(sub);
    }

    //works
    public void provisionAccess(Event event, StripeObject stripeObject) {
        Stripe.apiKey = "sk_test_51K6PnvAl7XnbPt50bAvU4L3nGTDI8nXn8a4nPhjTcbznNDfW3j7sBL1UqmL2x5yUVXygbNJ6o32Gg01juu76NkbJ00ereY9xEJ";
        Subscription subscription = (Subscription) stripeObject;
        com.fsd.hellovelo.entity.Subscription localSubscription = subscriptionRepository.findByStripeSubscriptionId(subscription.getId()).orElseThrow(() -> new ResourceNotFoundException("Error: Could not find subscription."));
//        User user = userRepository.findById(localSubscription.getId()).orElseThrow(() -> new ResourceNotFoundException("Error: User not found. LocalSubscriptionId: " + localSubscription.getId()));
        User user = localSubscription.getUser();
        user.setProvisionAccess(subscription.getStatus().equals("active"));

        userRepository.save(user);
    }

    public void recordInvoice(StripeObject stripeObject) {
        Stripe.apiKey = "sk_test_51K6PnvAl7XnbPt50bAvU4L3nGTDI8nXn8a4nPhjTcbznNDfW3j7sBL1UqmL2x5yUVXygbNJ6o32Gg01juu76NkbJ00ereY9xEJ";
        Invoice invoice = (Invoice) stripeObject;
        if(invoice.getBillingReason().equals("subscription_create")){
            return;
        }

        com.fsd.hellovelo.entity.Subscription subscription = subscriptionRepository.findByStripeSubscriptionId(invoice.getSubscription()).orElseThrow(() -> new ResourceNotFoundException("Subscription " + invoice.getSubscription() + " not found."));
        com.fsd.hellovelo.entity.Invoice localInvoice = invoiceRepository.findBySubscriptionAndInvoiceStatus(subscription, EInvoiceStatus.NOT_CREATED).orElseThrow(() -> new ResourceNotFoundException(("Invoice not found.")));

        Instant instant = Instant.ofEpochSecond(invoice.getPeriodEnd());

        localInvoice.setStripeInvoiceId(invoice.getId());
        localInvoice.setDateDue(LocalDate.ofInstant(instant, ZoneOffset.UTC));


        localInvoice.setInvoiceStatus(EInvoiceStatus.CREATED);
        invoiceRepository.save(localInvoice);
    }

    public void addDiscountsWhenInvoiceCreated(StripeObject stripeObject) throws StripeException {

        Stripe.apiKey = "sk_test_51K6PnvAl7XnbPt50bAvU4L3nGTDI8nXn8a4nPhjTcbznNDfW3j7sBL1UqmL2x5yUVXygbNJ6o32Gg01juu76NkbJ00ereY9xEJ";
        Invoice invoice = (Invoice) stripeObject;

        if(!invoice.getStatus().equals("draft")){
            return;
        }

        com.fsd.hellovelo.entity.Subscription subscription = subscriptionRepository.findByStripeSubscriptionId(invoice.getSubscription()).orElseThrow(() -> new ResourceNotFoundException("Error: Subscription " + invoice.getSubscription() + " not found."));
        com.fsd.hellovelo.entity.Invoice localInvoice = invoiceRepository.findBySubscriptionAndInvoiceStatus(subscription, EInvoiceStatus.CREATED).orElseThrow(() -> new ResourceNotFoundException(("Invoice not found.")));


        InvoiceItemCreateParams invoiceItemCreateParams = new InvoiceItemCreateParams.Builder()
                                                            .setCustomer(invoice.getCustomer())
                                                            .setSubscription(subscription.getStatus() == EPaymentStatus.CANCELED ? null : invoice.getSubscription())
                                                            .setAmount(localInvoice.getRentalDiscountSum() * -1)
                                                            .setInvoice(invoice.getId())
                                                            .setDescription("Discounts earned from moving bikes from full stations to empty stations.")
                                                            .build();
        InvoiceItem item = InvoiceItem.create(invoiceItemCreateParams);
    }

    public void deleteSubscription(Long userId) throws StripeException, NoSuchElementException {

        Stripe.apiKey = "sk_test_51K6PnvAl7XnbPt50bAvU4L3nGTDI8nXn8a4nPhjTcbznNDfW3j7sBL1UqmL2x5yUVXygbNJ6o32Gg01juu76NkbJ00ereY9xEJ";
        User user = userRepository.findById(userId).orElseThrow(() -> new ResourceNotFoundException("Error: User could not be found."));

        if(rentalRepository.findFirstByEndStationNullAndUserEquals(user).isPresent()){
            throw new IllegalArgumentException("Error: Cannot cancel a subscription while a bike is rented. Return the bike before canceling the subscription.");
        }
        System.out.println("delete");
        com.fsd.hellovelo.entity.Subscription subscription = subscriptionRepository.findFirstByUserAndTypeEqualsAndStatusNot(user, EType.BIKE, EPaymentStatus.CANCELED).orElseThrow();
        if(subscription.getStripeSubscriptionId() == null){
            throw new ResourceNotFoundException("stripeSub not found");
        }
        Subscription stripeSubscription = Subscription.retrieve(subscription.getStripeSubscriptionId());
        if(stripeSubscription == null){
            throw new ResourceNotFoundException("stripeSub obj not found");
        }
        Map<String, Object> subCancelParams = new HashMap<>();
        subCancelParams.put("invoice_now", true);

        stripeSubscription.cancel(subCancelParams);

        subscription.setStatus(EPaymentStatus.CANCELED);
        subscriptionRepository.save(subscription);
    }

    public com.fsd.hellovelo.entity.Subscription getSubscription(Long userId) throws StripeException {
        Stripe.apiKey = "sk_test_51K6PnvAl7XnbPt50bAvU4L3nGTDI8nXn8a4nPhjTcbznNDfW3j7sBL1UqmL2x5yUVXygbNJ6o32Gg01juu76NkbJ00ereY9xEJ";
        User user = userRepository.findById(userId).orElseThrow(() -> new ResourceNotFoundException("Error: User could not be found."));
        com.fsd.hellovelo.entity.Subscription subscription = subscriptionRepository.findFirstByUserAndTypeEqualsAndStatusNot(user, EType.BIKE, EPaymentStatus.CANCELED).orElseThrow(() -> new ResourceNotFoundException("You do not have a subscription!"));
        return subscription;
    }

    private void updateNextBillDate(com.fsd.hellovelo.entity.Subscription subscription) throws StripeException {
        Map<String, Object> invoiceParams = new HashMap<>();
        invoiceParams.put("subscription", subscription.getStripeSubscriptionId());

        Invoice invoice = Invoice.upcoming(invoiceParams);
        Instant instant = Instant.ofEpochSecond(invoice.getPeriodEnd());
        subscription.setNextPaymentDate(LocalDate.ofInstant(instant, ZoneOffset.UTC));
        subscriptionRepository.save(subscription);
    }

    private void retrieveInvoicePdf(com.fsd.hellovelo.entity.Subscription subscription) throws StripeException {
        Stripe.apiKey = "sk_test_51K6PnvAl7XnbPt50bAvU4L3nGTDI8nXn8a4nPhjTcbznNDfW3j7sBL1UqmL2x5yUVXygbNJ6o32Gg01juu76NkbJ00ereY9xEJ";

//        String lastInvoiceId = subscription.getLastInvoiceId();
//        if(lastInvoiceId == null){
//            return;
//        }
//        Invoice invoice = Invoice.retrieve(lastInvoiceId);
//
//        subscription.setInvoicePdfLink(invoice.getInvoicePdf());
//        System.out.println(subscription.getInvoicePdfLink());
    }

    //    public Object updatePaymentRequest() {
//        Stripe.apiKey = "sk_test_51K6PnvAl7XnbPt50bAvU4L3nGTDI8nXn8a4nPhjTcbznNDfW3j7sBL1UqmL2x5yUVXygbNJ6o32Gg01juu76NkbJ00ereY9xEJ";
//        UserDetailsImpl userDetails = (UserDetailsImpl) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
//        User user = userRepository.findById(userDetails.getId()).orElseThrow();
//        com.fsd.hellovelo.entity.Subscription subscription = subscriptionRepository.findFirstByUserAndTypeEqualsAndStatusNot(user, EType.BIKE, EPaymentStatus.CANCELED).orElseThrow();
//        SessionCreateParams params = SessionCreateParams.builder().addPaymentMethodType(SessionCreateParams.PaymentMethodType.CARD)
//                        .setMode(SessionCreateParams.Mode.SETUP)
//                        .setCustomer(userDetails.getStripeUserId())
//                        .setSetupIntentData( SessionCreateParams.SetupIntentData.builder()
//                                .putMetadata("customer_id", userDetails.getStripeUserId())
//                                .putMetadata("subscription_id", subscription.getStripeSubscriptionId())
//                                .build())
//                        .set
//    }

    //    private List<Discount> currentDiscounts(com.fsd.hellovelo.entity.Subscription subscription) throws StripeException {
//        Stripe.apiKey = "sk_test_51K6PnvAl7XnbPt50bAvU4L3nGTDI8nXn8a4nPhjTcbznNDfW3j7sBL1UqmL2x5yUVXygbNJ6o32Gg01juu76NkbJ00ereY9xEJ";
//        Map<String, Object> invoiceParams = new HashMap<>();
//        invoiceParams.put("subscription", subscription.getStripeSubscriptionId());
//
//        Invoice upcomingInvoice = Invoice.upcoming(invoiceParams);
//
//        List<String> discounts = upcomingInvoice.get();
//        List<Discount> discountList = new ArrayList<>();
//        for (String discount: discounts) {
//            System.out.println(discount);
//            com.stripe.model.Discount stripeDiscount = com.stripe.model.Discount.re
//            discountList.add(discountRepository.findByStripePromoCodeId(discount).orElse(null));
//        }
//
//        Subscription stripeSubscription = Subscription.retrieve(subscription.getStripeSubscriptionId());
//        Discount discount = discountRepository.findByStripePromoCodeId(stripeSubscription.getDiscount() == null ? null : stripeSubscription.getDiscount().getId()).orElse(null);
//
//        if(!discountList.contains(discount)){
//            discountList.add(discount);
//        }
//
//        return discountList;
//    }

//    public void recordLastInvoice(StripeObject stripeObject) throws StripeException{
//        Stripe.apiKey = "sk_test_51K6PnvAl7XnbPt50bAvU4L3nGTDI8nXn8a4nPhjTcbznNDfW3j7sBL1UqmL2x5yUVXygbNJ6o32Gg01juu76NkbJ00ereY9xEJ";
//        Invoice invoice = (Invoice) stripeObject;
//        Optional<com.fsd.hellovelo.entity.Subscription> subscription = subscriptionRepository.findByStripeSubscriptionId(invoice.getSubscription());
//        if(subscription.isPresent()){
//            com.fsd.hellovelo.entity.Subscription sub = subscription.get();
//            if(sub.getRentalDiscounts() <= 0){
//                return;
//            }
//            sub.setLastInvoiceId(invoice.getId());
//            subscriptionRepository.save(sub);
//        }
//    }
}
