package performa.batch;

import com.stripe.Stripe;
import com.stripe.exception.StripeException;
import com.stripe.model.Plan;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import oneit.appservices.batch.ORMBatch;
import oneit.logging.LogLevel;
import oneit.logging.LogMgr;
import oneit.logging.LoggingArea;
import oneit.objstore.ObjectTransaction;
import oneit.objstore.StorageException;
import oneit.objstore.rdbms.filters.EqualsFilter;
import oneit.utils.filter.CollectionFilter;
import oneit.utils.filter.Filter;
import oneit.utils.parsers.FieldException;
import performa.orm.PaymentPlan;
import performa.orm.types.CurrencyType;
import performa.orm.types.Interval;
import performa.orm.types.UsageType;
import performa.utils.StripeUtils;


public class PullStripeDataBatch  extends ORMBatch
{
    public static LoggingArea PULL_STRIPE_DATA_BATCH = LoggingArea.createLoggingArea("PullStripeDataBatch");

    @Override
    public void run(ObjectTransaction ot) throws StorageException, FieldException
    {
        try 
        {
            LogMgr.log (PULL_STRIPE_DATA_BATCH, LogLevel.PROCESSING1, "RUNNING Pull Stripe Data Batch");
                    
            Stripe.apiKey = StripeUtils.STRIPE_KEY;
            
            Map<String, Object> planParams  =   new HashMap<>();
            
            planParams.put("active", true);
            planParams.put("limit", 100);
            
            List<Plan>      plansList       =   Plan.list(planParams).getData();
            PaymentPlan[]   paymentPlans    =   PaymentPlan.searchAll(ot);
            
            for (PaymentPlan paymentPlan : paymentPlans)
            {
                paymentPlan.setDisabled(Boolean.TRUE);
            }
            
            for (Plan plan : plansList)
            {
                if(plan.getAmount() == null)
                {
                    // tired plans have null value for amount: performa is not using tired plans
                    continue;
                }
                
                Filter<PaymentPlan> filter      =   PaymentPlan.SearchByAll().andStripeReference(new EqualsFilter<>(plan.getId()));
                List<PaymentPlan>   activePlans =   (List<PaymentPlan>) CollectionFilter.filter(Arrays.asList(paymentPlans) , filter);
            
                PaymentPlan     paymentPlan; 
                
                if(activePlans != null && !activePlans.isEmpty())
                {
                    paymentPlan =   activePlans.get(0);
                    LogMgr.log (PULL_STRIPE_DATA_BATCH, LogLevel.PROCESSING1, "Updating exiting payment plan: " , paymentPlan, " to match stripe plan: ", plan);
                }
                else
                {
                    paymentPlan =   PaymentPlan.createPaymentPlan(ot);
                    LogMgr.log (PULL_STRIPE_DATA_BATCH, LogLevel.PROCESSING1, "Creating a new payment plan for stripe plan: ", plan);
                }
                
                Map<String, String> metadata    =   plan.getMetadata();
                String              activeJobs  =   metadata.get("ActiveJobs");
                String              linkedPlan  =   metadata.get("LinkedPlan");
               
                paymentPlan.setStripeReference(plan.getId());
                paymentPlan.setPlanName(plan.getNickname());
                paymentPlan.setCurrencyType(CurrencyType.forName(plan.getCurrency().toUpperCase()));
                paymentPlan.setAmount(plan.getAmount().doubleValue() / 100);
                paymentPlan.setInterval(Interval.forName(plan.getInterval().toUpperCase()));
//                paymentPlan.setIntervalCount(plan.getIntervalCount().intValue());
                paymentPlan.setIntervalCount(1);
                paymentPlan.setDisabled(Boolean.FALSE);
                paymentPlan.setProductReference(plan.getProduct());
                paymentPlan.setUsageType(UsageType.forName(plan.getUsageType().toUpperCase()));
                
//                if(plan.getTrialPeriodDays() != null)
//                {
//                    paymentPlan.setTrialPeriodDays(plan.getTrialPeriodDays().intValue());
//                }
                
                if(activeJobs != null)
                {
                    paymentPlan.setActiveJobCount(Integer.valueOf(activeJobs));
                }
                
                if(linkedPlan != null)
                {
                    paymentPlan.setLinkedPlanReference(linkedPlan);
                }
                
                LogMgr.log (PULL_STRIPE_DATA_BATCH, LogLevel.PROCESSING1, "Saving payment plan: " , paymentPlan, " mapped from stripe plan: ", plan);
            }   
        } 
        catch (StripeException ex) 
        {
            LogMgr.log(PULL_STRIPE_DATA_BATCH, LogLevel.PROCESSING1, ex, "Error while pulling plan details from stripe");

        }
    }
}