package performa.batch;

import com.stripe.Stripe;
import com.stripe.exception.APIConnectionException;
import com.stripe.exception.APIException;
import com.stripe.exception.AuthenticationException;
import com.stripe.exception.CardException;
import com.stripe.exception.InvalidRequestException;
import com.stripe.model.Plan;
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.parsers.FieldException;
import performa.orm.PaymentPlan;
import performa.orm.types.CurrencyType;
import performa.orm.types.Interval;
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<>();
            List<Plan>          plansList   =   Plan.list(planParams).getData();
            
            for (Plan plan : plansList)
            {
                PaymentPlan[]   paymentPlans  = PaymentPlan.SearchByAll().andStripeReference(new EqualsFilter<>(plan.getId())).search(ot);
                PaymentPlan     paymentPlan; 
                
                if(paymentPlans != null && paymentPlans.length > 0)
                {
                    paymentPlan =   paymentPlans[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");
                
                paymentPlan.setStripeReference(plan.getId());
                paymentPlan.setPlanName(plan.getName());
                paymentPlan.setDescription(plan.getStatementDescriptor());
                paymentPlan.setCurrencyType(CurrencyType.forName(plan.getCurrency().toUpperCase()));
                paymentPlan.setAmount(plan.getAmount().doubleValue() / 100);
                paymentPlan.setInterval(Interval.forName(plan.getInterval().toUpperCase()));
                paymentPlan.setIntervalCount(plan.getIntervalCount());
                paymentPlan.setTrialPeriodDays(plan.getTrialPeriodDays());
                
                if(activeJobs != null)
                {
                    paymentPlan.setActiveJobCount(Integer.valueOf(activeJobs));
                }
                
                LogMgr.log (PULL_STRIPE_DATA_BATCH, LogLevel.PROCESSING1, "Saving payment plan: " , paymentPlan, " mapped from stripe plan: ", plan);
            }   
        } 
        catch (AuthenticationException | InvalidRequestException | APIConnectionException | CardException | APIException | StorageException | FieldException | NumberFormatException ex) 
        {
            LogMgr.log(PULL_STRIPE_DATA_BATCH, LogLevel.PROCESSING1, ex, "Error while pulling plan details from stripe");

        }
    }
}