package com.fsd.hellovelo.service;

import com.fsd.hellovelo.entity.*;
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.PromotionCode;
import com.stripe.param.PromotionCodeCreateParams;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.time.LocalTime;
import java.time.ZoneOffset;

@Service
public class ReferralService {

    private final ReferralRepository referralRepository;
    private final UserRepository userRepository;
    private final SubscriptionRepository subscriptionRepository;
    private final CouponRepository couponRepository;
    private final DiscountRepository discountRepository;
    private final SendGridEmailService sendGridEmailService;

    @Autowired
    public ReferralService(ReferralRepository referralRepository,UserRepository userRepository, SubscriptionRepository subscriptionRepository, CouponRepository couponRepository, DiscountRepository discountRepository, SendGridEmailService sendGridEmailService){
        this.referralRepository = referralRepository;
        this.userRepository = userRepository;
        this.subscriptionRepository = subscriptionRepository;
        this.couponRepository = couponRepository;
        this.discountRepository = discountRepository;
        this.sendGridEmailService = sendGridEmailService;
    }


    public void createReferral(Referral referral) throws StripeException {
        Stripe.apiKey = "sk_test_51K6PnvAl7XnbPt50bAvU4L3nGTDI8nXn8a4nPhjTcbznNDfW3j7sBL1UqmL2x5yUVXygbNJ6o32Gg01juu76NkbJ00ereY9xEJ";
        UserDetailsImpl userDetails = (UserDetailsImpl) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        User user = userRepository.findById(userDetails.getId()).orElseThrow();

        if(!user.isProvisionAccess()){
            throw new IllegalArgumentException("Error: Only subscribed users can use the referral program!");
        }

        Subscription subscription = subscriptionRepository.findFirstByUserAndTypeEqualsAndStatusNot(user, EType.BIKE, EPaymentStatus.CANCELED).orElseThrow();

        if(userRepository.existsByEmail(referral.getReferralEmail())){
            throw new IllegalArgumentException("That user is already registered! You cannot refer users that are already in the system.");
        }

        Coupon coupon = couponRepository.findByTitle("referral_coupon").orElseThrow();

        PromotionCodeCreateParams referringCodeCreate = new PromotionCodeCreateParams.Builder()
                .setCoupon(coupon.getStripeCouponId())
                .setCustomer(user.getStripeUserId())
                .build();
        PromotionCodeCreateParams referredCodeCreate = new PromotionCodeCreateParams.Builder()
                .setCoupon(coupon.getStripeCouponId())
                .build();
        try{
            PromotionCode referringCode = PromotionCode.create(referringCodeCreate);
            PromotionCode referredCode = PromotionCode.create(referredCodeCreate);
            Discount referringDiscount = new Discount(subscription, user, referringCode.getId(), false, null, coupon, referringCode.getCode());
            Discount referredDiscount = new Discount(referredCode.getId(), false, null, coupon, referredCode.getCode());
            referredDiscount.setStripePromoCodeId(referredCode.getId());
//            referringDiscount.setStripePromoCodeId(referringCode.getId());
            discountRepository.save(referringDiscount);
            discountRepository.save(referredDiscount);
            referral.setReferringDiscount(referringDiscount);
            referral.setReferredDiscount(referredDiscount);
            referral.setReferringUser(user);
            referralRepository.save(referral);
            System.out.println(referral);
            sendGridEmailService.sendReferralEmail(referral);

        }catch (StripeException ex){
            throw new IllegalArgumentException("Error: Promo code could not be created.");
        }
    }
}
