package performa.form;

import java.util.HashMap;
import java.util.Map;
import oneit.appservices.config.ConfigMgr;
import oneit.servlets.forms.SubmissionDetails;
import oneit.servlets.process.SaveFP;
import oneit.utils.BusinessException;
import oneit.utils.math.NullArith;
import javax.servlet.http.HttpServletRequest;
import oneit.logging.LogLevel;
import oneit.logging.LogMgr;
import oneit.objstore.StorageException;
import oneit.servlets.forms.SuccessfulResult;
import oneit.servlets.process.ORMProcessState;
import com.stripe.exception.StripeException;
import com.stripe.model.Card;
import com.stripe.model.Charge;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import oneit.logging.LoggingArea;
import oneit.security.SecUser;
import oneit.utils.DateDiff;
import performa.intercom.utils.IntercomUtils;
import performa.orm.Company;
import performa.orm.CompanyUser;
import performa.orm.Job;
import performa.orm.types.AssessmentType;
import performa.orm.types.JobStatus;
import performa.utils.StripeUtils;


public class MakePaymentFP extends SaveFP
{

    public  static final String         STRIPE_KEY      =   ConfigMgr.getKeyfileString("stripe.key","");
    public  static final String         STRIPE_PUB_KEY  =   ConfigMgr.getKeyfileString("stripe.pubkey","");
    private static final LoggingArea    LOG             =   LoggingArea.createLoggingArea("MakePaymentFP");

    @Override
    public SuccessfulResult processForm(ORMProcessState process, SubmissionDetails submission, Map p) throws BusinessException, StorageException
    {
        HttpServletRequest  request     =   submission.getRequest();
        Boolean             ppj         =   request.getAttribute("PPJ") != null ? (Boolean) request.getAttribute("PPJ") : Boolean.FALSE;
        Boolean             editCard    =   request.getAttribute("EditCard") != null ? (Boolean) request.getAttribute("EditCard") : Boolean.FALSE;
        Boolean             replaceCard =   request.getAttribute("ReplaceCard") != null ? (Boolean) request.getAttribute("ReplaceCard") : Boolean.FALSE;
        SecUser             secUser     =   SecUser.getTXUser(process.getTransaction());
        CompanyUser         companyUser =   secUser.getExtension(CompanyUser.REFERENCE_CompanyUser);
        Company             company     =   companyUser.getCompany();
        Job                 job         =   (Job) process.getAttribute("Job");

        LogMgr.log(LOG, LogLevel.PROCESSING1,"In MakePaymentFP from customer to open job: "  + company.getStripeReference());

        if(editCard)
        {
            UpdateCardFP.updateCardDetails(process, submission);
        }
        
        if(replaceCard)
        {
            ReplaceCardFP.replaceCardDetails(process, submission);
        }
        
        if(company.getCardID() != null && ppj)
        {
            try
            {
                Map<String, Object> chargeParams = new HashMap<>();
                chargeParams.put("amount", NullArith.intVal(NullArith.multiply(job.getAssessmentType() == AssessmentType.COMPREHENSIVE ? 499.0 : 399.0, 100, 0d)));
                chargeParams.put("currency", "aud");
                chargeParams.put("description", "Charges of creating job");
                chargeParams.put("customer", company.getStripeReference());

                Charge.create(chargeParams);
            }
            catch (StripeException e)
            {
                LogMgr.log(LOG, LogLevel.PROCESSING1, e, "Error while making a payment of company stripe " + company.getStripeReference());

                throw new BusinessException("Stripe payment was failed, Please contact adminstrator for more info.");
            }
        }

        if(company.getCardID() == null)
        {
            Card    card    =   StripeUtils.retrieveCard(company);

            company.setNameOnCard(card.getName());
            company.setCardPostCode(card.getAddressZip());
            company.setCardID(card.getId());
        }
        
        job.setApplyBy(DateDiff.add(DateDiff.getToday(), Calendar.DATE, 30));
        job.setOpenDate(new Date());
        job.setJobStatus(JobStatus.OPEN);
        job.setLastEdited(new Date());
        job.setIsPPJ(ppj);
        
        if(job.getShortenedURL() == null)
        {
            job.createShortenedURL();
        }
        
        if(!ppj && company.getPaymentPlan() != null)
        {
            // cannot subscribe to a plan without card details
//            company.setPlanRenewedOn(DateDiff.getToday());
//            company.setUsedCredits(1);
            
            StripeUtils.updatePlan(company);
        }
        
        // restarting process as custom attributes needs to be updated to intercom
        
        Set<String> attribsToRestore    =   new HashSet<>();
        attribsToRestore.add("Job");
        attribsToRestore.add("Company");
                
        completeProcessRestartAndRestoreAttribs(process, attribsToRestore);
        
        secUser     =   SecUser.getTXUser(process.getTransaction());
        companyUser =   secUser.getExtension(CompanyUser.REFERENCE_CompanyUser);

        // Update company in intercom
        if(companyUser.getCompany() != null)
        {
            IntercomUtils.updateCompany(companyUser.getCompany());
        }
        
        return super.processForm(process, submission, p);
    }
}