package performa.form;

import com.stripe.model.Coupon;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import oneit.logging.LogLevel;
import oneit.logging.LogMgr;
import oneit.objstore.ObjectTransaction;
import oneit.objstore.StorageException;
import oneit.objstore.rdbms.filters.EqualsFilter;
import oneit.servlets.forms.RedisplayResult;
import oneit.servlets.forms.SubmissionDetails;
import oneit.servlets.forms.SuccessfulResult;
import oneit.servlets.process.ORMProcessState;
import oneit.servlets.process.ProcessRedirectResult;
import oneit.servlets.process.SaveFP;
import oneit.utils.BusinessException;
import oneit.utils.DateDiff;
import performa.orm.HiringTeam;
import performa.orm.StripeCoupon;
import performa.orm.types.CouponDuration;
import performa.utils.StripeUtils;


public class ApplyCouponFP  extends SaveFP
{
    @Override
    public SuccessfulResult processForm(ORMProcessState process, SubmissionDetails submission, Map params) throws BusinessException, StorageException
    {
        HttpServletRequest  request     =   submission.getRequest();
        ObjectTransaction   objTran     =   process.getTransaction();
        HiringTeam          hiringTeam  =   (HiringTeam) process.getAttribute("HiringTeam");
        Boolean             firstTime   =   request.getAttribute("firstTime") != null ? (Boolean) request.getAttribute("firstTime") : Boolean.FALSE;

        LogMgr.log(HiringTeam.LOG, LogLevel.PROCESSING1, "Inside ApplyCouponFP for ", hiringTeam );

        if(hiringTeam.getCoupon() != null && hiringTeam.getCoupon().getCouponCode().equals(hiringTeam.getCouponCode()))
        {
            LogMgr.log(HiringTeam.LOG, LogLevel.PROCESSING1, "Inside ApplyCouponFP for ", hiringTeam , " already has a coupon added with coupon code: ", hiringTeam.getCouponCode());
            return RedisplayResult.getInstance();
        }
        
        if(firstTime && hiringTeam.isTrue(hiringTeam.getIsPPJ()))
        {
            hiringTeam.setIsPPJ(null);
        }
        
        Coupon          coupon          =   StripeUtils.retrieveCoupon(hiringTeam.getCouponCode());
        StripeCoupon[]  stripeCoupons   =   StripeCoupon.SearchByAll()
                                                        .andCouponCode(new EqualsFilter<>(hiringTeam.getCouponCode()))
                                                        .search(objTran);
        
        // only allowing coupons with percentage off
        if(coupon != null && coupon.getValid() && coupon.getPercentOff() != null)
        {
            StripeUtils.applyCoupon(hiringTeam);
            
            StripeCoupon stripeCoupon   =   null; 
            
            if(stripeCoupons != null && stripeCoupons.length > 0)
            {
                stripeCoupon =   stripeCoupons[0];
                LogMgr.log (HiringTeam.LOG, LogLevel.PROCESSING1, "Using an already created coupon : " , stripeCoupon);
            }
            else
            {
                stripeCoupon =   StripeCoupon.createStripeCoupon(objTran);
            
                stripeCoupon.setCouponCode(coupon.getId());
                stripeCoupon.setDurationInMonths(coupon.getDurationInMonths() != null ? coupon.getDurationInMonths().intValue() : 0);
                stripeCoupon.setPercentageOff(coupon.getPercentOff() != null ? coupon.getPercentOff().doubleValue() : 0d);
                stripeCoupon.setCouponDuration(CouponDuration.forName(coupon.getDuration().toUpperCase()));
                stripeCoupon.setMaxRedemptions(coupon.getMaxRedemptions() != null ? coupon.getMaxRedemptions().intValue() : 0);
                stripeCoupon.setTimesRedeemed(coupon.getTimesRedeemed() != null ? coupon.getTimesRedeemed().intValue() : 0);

                if(coupon.getRedeemBy() != null)
                {
                    stripeCoupon.setRedeemBy(new Date(coupon.getRedeemBy() * 1000));
                }
                LogMgr.log (HiringTeam.LOG, LogLevel.PROCESSING1, "Creating a new coupon for coupon code: ", hiringTeam.getCouponCode());
            }
            
            
            if(stripeCoupon.getCouponDuration() == CouponDuration.REPEATING)
            {
                hiringTeam.setCouponExpiryDate(DateDiff.add(new Date(), Calendar.MONTH, stripeCoupon.getDurationInMonths()));
            }
            
            hiringTeam.setCoupon(stripeCoupon);
        }
        else
        {
            return new ProcessRedirectResult((String) request.getAttribute("nextPage"),  new String[]{ "invalidcoupon", "true"});
        }
        
        return super.processForm(process, submission, params);
    }
}