package performa.form;

import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import oneit.components.ParticipantInitialisationContext;
import oneit.email.ConfigurableArticleTemplateEmailer;
import oneit.logging.*;
import oneit.objstore.ObjectTransaction;
import oneit.objstore.StorageException;
import oneit.objstore.parser.BusinessObjectParser;
import oneit.security.SecUser;
import oneit.servlets.forms.*;
import oneit.servlets.process.*;
import oneit.utils.*;
import performa.orm.*;
import performa.orm.types.*;
import performa.utils.Utils;
 

public class SendVerificationMailFP extends SaveFP
{
    private static final LoggingArea  LOG                 =   LoggingArea.createLoggingArea("SendVerificationLink");
    protected ConfigurableArticleTemplateEmailer  emailer;

    
    @Override
    public void validate(ORMProcessState process, SubmissionDetails submission, MultiException exceptions, Map params) throws StorageException 
    {
        HttpServletRequest  request     =   submission.getRequest();
        Job                 job         =   (Job) request.getAttribute("Job");
        Company             company     =   (Company) request.getAttribute("Company");

        Debug.assertion(company != null || job != null, "BO not avaialble");
        
        if(company != null)
        {
            CompanyUser companyUser =   company.getAddedByUser();
            SecUser     secUser     =   companyUser.getUser();
            
            BusinessObjectParser.assertFieldCondition(!Utils.emailExists(process.getTransaction(), secUser.getEmail()), secUser, SecUser.FIELD_Email, "emailExists", exceptions, true, request);
            BusinessObjectParser.assertFieldCondition(companyUser.isTrue(companyUser.getPrivacyPolicyAgreed()), companyUser, CompanyUser.FIELD_PrivacyPolicyAgreed, "agreePrivacy", exceptions, true, request);
            BusinessObjectParser.assertFieldCondition(companyUser.isTrue(companyUser.getConditionsAgreed()), companyUser, CompanyUser.FIELD_ConditionsAgreed, "agreeTerms", exceptions, true, request);
            BusinessObjectParser.assertFieldCondition(companyUser.getPhone() != null , companyUser, CompanyUser.FIELD_Phone, "mandatory", exceptions, true, request);
        }
        else
        {
            JobApplication      jobApplication  =   (JobApplication)request.getAttribute("JobApplication");
            Candidate           candidate       =   (Candidate) request.getAttribute("Candidate");
            SecUser             secUser         =   candidate.getUser();
        
            BusinessObjectParser.assertFieldCondition(secUser.getEmail() != null , job, Job.FIELD_Email, "mandatory", exceptions, true, request);
            BusinessObjectParser.assertFieldCondition(StringUtils.isEmailAddress(secUser.getEmail()), job, Job.FIELD_Email, "invalid", exceptions, true, request);
            
            BusinessObjectParser.assertFieldCondition(secUser.getFirstName() != null, secUser, SecUser.FIELD_FirstName, "mandatory", exceptions, true, request);
            BusinessObjectParser.assertFieldCondition(secUser.getLastName() != null, secUser, SecUser.FIELD_LastName, "mandatory", exceptions, true, request);

            BusinessObjectParser.assertFieldCondition(candidate.isTrue(candidate.getPrivacyPolicyAgreed()), candidate, Candidate.FIELD_PrivacyPolicyAgreed, "agreePrivacy", exceptions, true, request);
            BusinessObjectParser.assertFieldCondition(candidate.isTrue(candidate.getConditionsAgreed()), candidate, Candidate.FIELD_ConditionsAgreed, "agreeTerms", exceptions, true, request);

            if(job.getRequireCV())
            {
                BusinessObjectParser.assertFieldCondition(jobApplication.getCV() != null , jobApplication, JobApplication.FIELD_CV, "uploadCV", exceptions, true, request);
                BusinessObjectParser.assertFieldCondition(jobApplication.getCoverLetter() != null , jobApplication, JobApplication.FIELD_CoverLetter, "uploadCover", exceptions, true, request);
            }
            
            BusinessObjectParser.assertFieldCondition(candidate.getGoogleAddressText() != null, candidate, Candidate.FIELD_GoogleAddressText, "mandatory", exceptions, true, request);
            BusinessObjectParser.assertFieldCondition(candidate.isTrue(candidate.getHasValidAddress()), candidate, Candidate.FIELD_GoogleAddressText, "invalid", exceptions, true, request);
        }
        
        super.validate(process, submission, exceptions, params);
    }
    
    
    @Override 
    public SuccessfulResult processForm(ORMProcessState process, SubmissionDetails submission, Map params) throws BusinessException, StorageException
    {
        HttpServletRequest  request         =   submission.getRequest();
        ObjectTransaction   objTran         =   process.getTransaction();
        Job                 job             =   (Job) request.getAttribute("Job");
        Candidate           candidate       =   (Candidate) request.getAttribute("Candidate");
        Company             company         =   (Company) request.getAttribute("Company");
        JobApplication      jobApplication  =   (JobApplication) request.getAttribute("JobApplication");

        if(company != null)
        {
            CompanyUser companyUser         =   company.getAddedByUser();
            SecUser     secUser             =   companyUser.getUser();
            SecUser     availableSecUser    =   SecUser.searchNAME(objTran, secUser.getEmail());
            
            LogMgr.log(LOG, LogLevel.PROCESSING1, "Started to send varification email.", companyUser);
                            
            if(availableSecUser!=null)
            {
                if(availableSecUser.getExtension(CompanyUser.REFERENCE_CompanyUser)!=null)
                {
                    Debug.assertion(false, "user available", availableSecUser);
                }
                else
                {
                    LogMgr.log(LOG, LogLevel.PROCESSING1, "SecUser available", availableSecUser);

                    availableSecUser.addToExtensions(companyUser);

                    //remove new sec user obj
                    secUser.removeFromExtensions(companyUser);
                    secUser.delete();
                }
            }
            else
            {

                secUser.setUserName(secUser.getEmail().toLowerCase());
                secUser.setAttribute("md5:" + SecUser.FIELD_Password, CompanyUser.DEFAULT_PASSWORD);
                secUser.addRole(Utils.getRole(Utils.ROLE_CLIENT, objTran));
                
                LogMgr.log(LOG, LogLevel.PROCESSING1, "New user created :: ", secUser);
            }
            
            //set default to admin
            companyUser.setRole(RoleType.ADMIN);
            
            if(companyUser.getDefaultHiringTeam() != null)
            {
                companyUser.getDefaultHiringTeam().setHiringTeamName(company.getCompanyName());
            }
            
            Utils.sendVerificationMail(job, companyUser, request, emailer, SendVerificationMailFP.class.getName());

            LogMgr.log(LOG, LogLevel.PROCESSING1, "End of sending varification email.", companyUser);
        }
        else
        {
            if(candidate.isTrue(candidate.getIsEmailIngest()))
            {
                if(candidate.isTrue(candidate.getIsMaskedEmail()))
                {
                    SecUser   old   =     (SecUser) candidate.getUser().getEarliestBackup();
                
                    if(CollectionUtils.equals(old.getEmail(), candidate.getUser().getEmail()))
                    {
                        throw new BusinessException("Please enter a valid email address");
                    }
                
                    //set new verification key as email changed
                    candidate.setVerificationKey(new RandomStringGen().generateAlphaNum(6));
                    
                    candidate.getUser().setUserName(candidate.getUser().getEmail());
                    candidate.setIsMaskedEmail(false);
                    candidate.setKnownAsAlias(old.getEmail());
                }
                else
                {
                    candidate.setIsAccountVerified(true);
                }
                
                jobApplication.setApplicationStatus(ApplicationStatus.DRAFT);
            }
            
            if(!candidate.isTrue(candidate.getIsPasswordChanged()))
            {
                candidate.setIsPasswordChanged(true);
            }
            
            // storing candidate location in application for distance calculation to be accurate even if user edits 
            // location in the next application
            jobApplication.setGoogleAddressText(candidate.getGoogleAddressText());
        }

        return super.processForm(process, submission, params);
    }
    
    
    @Override
    public void init(ParticipantInitialisationContext context) throws InitialisationException
    {
        super.init(context);
        
        emailer = (ConfigurableArticleTemplateEmailer) (context.getSingleChild("AccountVerificationEmailer"));
    }
}