package performa.form;

import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import oneit.appservices.config.ConfigMgr;
import oneit.components.ParticipantInitialisationContext;
import oneit.email.ConfigurableArticleTemplateEmailer;
import oneit.email.ConfigurableEmailerException;
import oneit.logging.*;
import oneit.objstore.StorageException;
import oneit.objstore.parser.BusinessObjectParser;
import oneit.objstore.validator.AttributeValidator;
import oneit.security.SecUser;
import oneit.servlets.forms.*;
import oneit.servlets.process.*;
import oneit.servlets.security.SessionSecUserDecorator;
import oneit.utils.*;
import oneit.utils.parsers.FieldException;
import performa.intercom.utils.IntercomUtils;
import performa.orm.*;
import performa.utils.Utils;
import performa.utils.WebUtils;
 

public class VerifyCompanyUserFP extends ORMProcessFormProcessor
{
    private static final LoggingArea    LOG =   LoggingArea.createLoggingArea("VerifyCompanyUser");
    protected ConfigurableArticleTemplateEmailer  emailer;

    @Override
    public void validate(ORMProcessState process, SubmissionDetails submission, MultiException exceptions, Map params) throws StorageException
    {
        HttpServletRequest  request     =   submission.getRequest();
        CompanyUser         companyUser =   (CompanyUser) process.getAttribute("CompanyUser");
        Boolean             socialLogin =   (Boolean) request.getAttribute("socialLogin");
        SecUser             secUser     =   companyUser.getUser();
        Company             company     =   companyUser.getCompany();
        
        if(socialLogin)
        {
            BusinessObjectParser.assertFieldCondition(secUser.getEmail()!=null, secUser, SecUser.FIELD_Email, "invalid", exceptions, true, request);
            BusinessObjectParser.assertFieldCondition(!Utils.isCompanyUserEmailFound(secUser.getTransaction(), secUser.getEmail()), secUser, SecUser.FIELD_Email, "emailExists", exceptions, true, request);
        }
        else
        {
            BusinessObjectParser.assertFieldCondition(StringUtils.isEmailAddress(secUser.getUserName()), secUser, SecUser.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);
        
        if(!company.isTrue(company.getIsVerified()))
        {
            BusinessObjectParser.assertFieldCondition(company.getCompanyName()!=null, company, Company.FIELD_CompanyName, "mandatory", exceptions, true, request);
        }
        
        if(!socialLogin)
        {
            BusinessObjectParser.assertFieldCondition(companyUser.getPassword()!= null, companyUser, CompanyUser.FIELD_Password, "mandatory", exceptions, true, request);
            BusinessObjectParser.assertFieldCondition(companyUser.getConfirmPassword()!= null, companyUser, CompanyUser.FIELD_ConfirmPassword, "mandatory", exceptions, true, request);
            BusinessObjectParser.assertFieldCondition(CollectionUtils.equals(companyUser.getPassword(), companyUser.getConfirmPassword()), companyUser, CompanyUser.FIELD_ConfirmPassword, "passwordNotMatch", exceptions, true, request);
        
            //to validate password
            AttributeValidator passwordValidator = (AttributeValidator)(ConfigMgr.getConfigObject ("CONFIG.ORMVALIDATOR", "PasswordValidator", null));

            try
            {
                //execute if not null
                if (passwordValidator != null)
                {
                    passwordValidator.validate (null, secUser, "Password", companyUser.getPassword());
                }
            }
            catch (FieldException e)
            {
                exceptions.addException(new FieldException(e, CompanyUser.FIELD_Password));
            }
            catch (Exception e)
            {
                throw NestedException.wrap(e);
            }
        }
        super.validate(process, submission, exceptions, params);
    }


    @Override
    public SuccessfulResult processForm(ORMProcessState process, SubmissionDetails submission, Map params) throws BusinessException, StorageException
    {
        HttpServletRequest  request         =   submission.getRequest();
        CompanyUser         companyUser     =   (CompanyUser) process.getAttribute("CompanyUser");
        SecUser             secUser         =   companyUser.getUser();
        Company             company         =   companyUser.getCompany();
        String              nextPage        =   (String) request.getAttribute("nextPage");
        Boolean             socialLogin     =   (Boolean) request.getAttribute("socialLogin");

        LogMgr.log(LOG, LogLevel.PROCESSING1, "Verifing User", companyUser, secUser);

        if(CollectionUtils.equals(companyUser.getPassword(), companyUser.getConfirmPassword()))
        {           
            if(!company.isTrue(company.getIsVerified()) && CollectionUtils.equals(company.getAddedByUser(), companyUser))
            {
                process.setAttribute("Company", company);
                process.setAttribute("socialLogin", socialLogin);
                
                return new ProcessRedirectResult(nextPage, new String[0]);
            }
            else
            {
                nextPage    =   WebUtils.getArticleByShortCut(process.getTransaction(), WebUtils.ADMIN_HOME).getLink(request);
                
                 // Create company user in intercom
                
                performa.intercom.resources.Company intercomCompany =   IntercomUtils.findCompanyByID(company);

                IntercomUtils.createIntercomUser(secUser, "Hiring Team", intercomCompany);
            }
            
            if(!socialLogin)
            {
                secUser.setAttribute("md5:" + SecUser.FIELD_Password, companyUser.getPassword());
            }
            
            companyUser.setIsAccountVerified(Boolean.TRUE);

            sendMail(companyUser, request);

            request.getSession().setAttribute (SecUser.SEC_USER_ID, secUser);
            request.getSession().setAttribute (SessionSecUserDecorator.REFRESH_SECURITY, Boolean.TRUE);

            LogMgr.log(LOG, LogLevel.PROCESSING1, "Password resetted", companyUser, secUser);
        }
        
        LogMgr.log(LOG, LogLevel.PROCESSING1, "Verifing User finished", companyUser, secUser);
        
        process.completeAndRestart();
        
        return new ProcessRedirectResult(nextPage, new String[0]);
    }

    
    @Override
    public void init(ParticipantInitialisationContext context) throws InitialisationException
    {
        super.init(context);
        
        emailer = (ConfigurableArticleTemplateEmailer) (context.getSingleChild("AccountCreatedEmailer"));
    }
    
    
    protected void sendMail(CompanyUser companyUser, HttpServletRequest request) throws BusinessException
    {
        try
        {
            LogMgr.log(LOG, LogLevel.PROCESSING1, "Sending Account Created mail from  VerifyCompanyUserFP to :: ", companyUser);

            Map             defaultParams   =   CollectionUtils.EMPTY_MAP;
            ObjectTransform transform       =   Utils.createCompoundTransform(defaultParams, companyUser);

            Utils.sendMail(emailer, transform, new String[]{companyUser.getEmailAddressFromUser()}, null, companyUser);

            LogMgr.log(LOG, LogLevel.PROCESSING1, "Sent Account Created mail successfully from " + VerifyCompanyUserFP.class + " to :: ", companyUser);
        }
        catch (ConfigurableEmailerException ex)
        {
            LogMgr.log(LOG, LogLevel.SYSTEMERROR1, ex, "Error occured while sending mail for CompanyUser :: " + companyUser);

            throw new BusinessException("We are unable to send mail. Please try again or contact Talentology for more details.");
        }
    }
}