package performa.form;

import javax.servlet.http.HttpServletRequest;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import oneit.logging.LogLevel;
import oneit.logging.LogMgr;
import oneit.objstore.StorageException;
import oneit.objstore.parser.BusinessObjectParser;
import oneit.security.SecUser;
import oneit.servlets.forms.SubmissionDetails;
import oneit.servlets.forms.SuccessfulResult;
import oneit.servlets.process.ORMProcessState;
import oneit.servlets.process.SaveFP;
import oneit.utils.BusinessException;
import oneit.utils.DateDiff;
import oneit.utils.MultiException;
import oneit.utils.math.NullArith;
import performa.intercom.utils.IntercomUtils;
import performa.orm.*;
import performa.orm.types.*;
import performa.utils.StripeUtils;


public class SaveJobFP extends SaveFP 
{
    @Override
    public SuccessfulResult processForm(ORMProcessState process, SubmissionDetails submission, Map params) throws BusinessException, StorageException
    {
        HttpServletRequest  request         =   submission.getRequest();
        Job                 job             =   request.getAttribute("Job") != null ? (Job) request.getAttribute("Job") : (Job) process.getAttribute("Job");
        JobStatus           status          =   (JobStatus) request.getAttribute("JobStatus");
        DraftLocation       draftLocation   =   (DraftLocation) request.getAttribute("DraftLocation");
        SecUser             secUser         =   SecUser.getTXUser(process.getTransaction());
        CompanyUser         companyUser     =   secUser.getExtension(CompanyUser.REFERENCE_CompanyUser);
        Company             company         =   companyUser.getCompany();
        HiringTeam          hiringTeam      =   job.getHiringTeam();
        HiringTeam          billingTeam     =   hiringTeam.getManageOwnBilling() ? hiringTeam : hiringTeam.getBilledByTeam();
        
        LogMgr.log(Job.LOG, LogLevel.PROCESSING1,"In SaveJobFP saving job : ", job );

        if(status != null)
        {
            LogMgr.log(Job.LOG, LogLevel.PROCESSING1,"In SaveJobFP setting job status to session : ", status );

            request.getSession().setAttribute("JobStatus", status);
        }
        
        Job oldJob  = (Job) job.getEarliestBackup();
        
        if(oldJob != null && oldJob.getJobStatus() == JobStatus.DRAFT && (job.getJobStatus() == JobStatus.OPEN || status == JobStatus.OPEN))
        {
            job.setApplyBy(DateDiff.add(DateDiff.getToday(), Calendar.DATE, 30));
            job.setOpenDate(new Date());
            
            if (!billingTeam.canCreateJob())
            {
                throw new BusinessException("Please change payment plan settings to open this job");
            }
            
            billingTeam.setUsedCredits(NullArith.add(billingTeam.getUsedCredits(), 1).intValue());
            
            if(billingTeam.getUsedCredits() > billingTeam.getAvailableCredits())
            {
                StripeUtils.recordUsage(billingTeam);
            }
            
            if(status == JobStatus.OPEN)
            {
//                if(hiringTeam.getSelectedPaymentPlan() != null)
//                {
//                    company.setPaymentPlan(company.getSelectedPaymentPlan());
//                
//                    LogMgr.log(Company.LOG, LogLevel.PROCESSING1,"Company payment plan updated.", job, company, company.getPaymentPlan());
//                }
                
                job.setJobStatus(status);

                LogMgr.log(Job.LOG, LogLevel.PROCESSING1,"Job status changed as Open. ", job );
            }
        }
        
        if(job.getJobStatus() == JobStatus.OPEN && job.getShortenedURL() == null)
        {
            job.createShortenedURL();
        }
        
        if(job.getJobStatus() == JobStatus.COMPLETE)
        {
            job.setIsManuallyClosed(Boolean.TRUE);
        }
        
        job.setLastEdited(new Date());
        
        if(draftLocation != null)
        {
            job.setDraftLocation(draftLocation);
        }
        
        if(job.getOccupationId() != null)
        {
            job.setOccupation(Occupation.getOccupationByID(process.getTransaction(), Long.valueOf(job.getOccupationId())));
        }
        
        // restarting process as custom attributes needs to be updated to intercom
        completeProcessRestartAndRestoreAttribs(process, request);
        
        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, params);
    }
    
    @Override
    public void validate(ORMProcessState process, SubmissionDetails submission, MultiException exceptions, Map params) throws StorageException
    {
        HttpServletRequest  request         =   submission.getRequest();
        Job                 job             =   process.getAttribute("Job") != null ? (Job) process.getAttribute("Job") : (Job) request.getAttribute("Job");
        Boolean             openJob         =   (Boolean) request.getAttribute("openJob");
        JobStatus           status          =   (JobStatus) request.getAttribute("JobStatus");
        SecUser             loggedInUser    =   SecUser.getTXUser(process.getTransaction());
        CompanyUser         companyUser     =   loggedInUser.getExtension(CompanyUser.REFERENCE_CompanyUser);
        HiringTeam          hiringTeam      =   job.getHiringTeam();
        HiringTeam          billingTeam     =   hiringTeam.getManageOwnBilling() ? hiringTeam : hiringTeam.getBilledByTeam();

        if(job.getJobStatus() != JobStatus.DRAFT || openJob == Boolean.TRUE)
        {
            BusinessObjectParser.assertFieldCondition(job.getLevel() != null, job , Job.SINGLEREFERENCE_Level, "mandatory", exceptions, true, request);
            
            if(job.getLevel() != null)
            {
                BusinessObjectParser.assertFieldCondition(job.showLevelOption(job.getLevel()), job , Job.SINGLEREFERENCE_Level, "invalid", exceptions, true, request);
            }
        }
        
        //to select payment plan when job open
        if(status != null && status == JobStatus.OPEN)
        {
//            BusinessObjectParser.assertFieldCondition(company.getSelectedPaymentPlan() != null || company.getPaymentPlan() != null, company, Company.SINGLEREFERENCE_PaymentPlan, "mandatory", exceptions, true, request);
            
//            if(company.getSelectedPaymentPlan() != null)
//            {
                BusinessObjectParser.assertFieldCondition(billingTeam.canCreateJob() , job, Job.FIELD_JobStatus, "insufficientCredit", exceptions, true, request);
//            }
        }
        
        if(job.getJobStatus() == JobStatus.OPEN)
        {
            BusinessObjectParser.assertFieldCondition(billingTeam.getCardID() != null , billingTeam, HiringTeam.FIELD_CardID, "mandatoryCardDetails", exceptions, true, request);
            
            BusinessObjectParser.assertFieldCondition(billingTeam.canCreateJob() , job, Job.FIELD_JobStatus, "insufficientCredit", exceptions, true, request);
        }
        
        super.validate(process, submission, exceptions, params);
    }
}