package performa.form;

import java.util.Date;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import oneit.business.content.Article;
import oneit.components.ParticipantInitialisationContext;
import oneit.email.ConfigurableArticleTemplateEmailer;
import oneit.email.ConfigurableEmailerException;
import oneit.logging.*;
import oneit.net.LoopbackHTTP;
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.servlets.utils.NotificationUtils;
import oneit.utils.*;
import performa.orm.*;
import performa.utils.Utils;
import performa.utils.WebUtils;
 

public class SendUserInvitationFP extends SaveFP
{
    private static LoggingArea  LOG                 =   LoggingArea.createLoggingArea("SendUserInvitationFP");
    private static final String DEFAULT_PASSWORD    =   "Talentology123";
    protected ConfigurableArticleTemplateEmailer invitationEmailer;
    
    
    @Override
    public void validate(ORMProcessState process, SubmissionDetails submission, MultiException exceptions, Map params) throws StorageException 
    {
        HttpServletRequest  request =   submission.getRequest();
        Company             company =   (Company) process.getAttribute("Company");
        
        BusinessObjectParser.assertFieldCondition(company.getUserEmail()!=null, company, Company.FIELD_UserEmail, "mandatory", exceptions, true, request);
        BusinessObjectParser.assertFieldCondition(!isEmailFound(process.getTransaction(), company.getUserEmail()), company, Company.FIELD_UserEmail, "emailExists", exceptions, true, request);
        BusinessObjectParser.assertFieldCondition(company.getRoleType()!=null, company, Company.FIELD_RoleType, "mandatory", 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();
        Company             company     =   (Company) process.getAttribute("Company");

        LogMgr.log(LOG, LogLevel.PROCESSING1, "Started to create new use", company);

        SecUser             newUser     =   SecUser.createSecUser(objTran);
        CompanyUser         newComUser  =   newUser.getExtensionOrCreate(CompanyUser.REFERENCE_CompanyUser);
        
        newUser.setUserName(company.getUserEmail().toLowerCase());
        newUser.setEmail(newUser.getUserName());
        newUser.setAttribute("md5:" + SecUser.FIELD_Password, DEFAULT_PASSWORD);
        newUser.addRole(Utils.getRole(Utils.ROLE_CLIENT, objTran));
        newUser.setFirstName(company.getFirstName());
        newUser.setLastName(company.getLastName());
        
        newComUser.setCompany(company);
        newComUser.setRole(company.getRoleType());

        LogMgr.log(LOG, LogLevel.PROCESSING1, "New user created :: ", newUser);
        
        sendInvitationMail(newComUser, request);

        LogMgr.log(LOG, LogLevel.PROCESSING1, "End of sending invitation email.", newUser);

        return super.processForm(process, submission, params);
    }

    
    @Override
    public void init(ParticipantInitialisationContext context) throws InitialisationException
    {
        super.init(context);
        
        invitationEmailer   =   (ConfigurableArticleTemplateEmailer) (context.getSingleChild("InvitationEmailer"));
    }
    
    
    protected void sendInvitationMail(CompanyUser companyUser, HttpServletRequest request) throws BusinessException
    {
        if(companyUser.getIsAccountVerified()!=Boolean.TRUE)
        {
            try
            {
                LogMgr.log(LOG, LogLevel.PROCESSING1, "Sending invitation mail from  SendUserInvitationFP to :: ", companyUser);

                Article         invitationArticle =   WebUtils.getArticleByShortCut(companyUser.getTransaction(), WebUtils.COMPANY_ACCOUNT_VERIFICATION);
                RandomStringGen random              =   new RandomStringGen();

                //set invitation key and send mail time
                companyUser.setVerificationKey(random.generateAlphaNum(6));
                companyUser.setVerificationMailSendDate(new Date());

                String          link                =   LoopbackHTTP.getRemoteAccessURL(request) 
                                                            + invitationArticle.getLink(request, CollectionUtils.EMPTY_MAP, "/") 
                                                            + "?id=" + companyUser.getID()
                                                            + "&key=" + companyUser.getVerificationKey();
                Map             defaultParams       =   CollectionUtils.mapEntry("link", link).toMap(); 
                ObjectTransform transform           =   Utils.createCompoundTransform(defaultParams, companyUser);

                Utils.sendMail(invitationEmailer, transform, new String[]{companyUser.getUser().getUserName()}, null, companyUser);

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

                throw new BusinessException("We are unable to send mail. Please try again or contact Talentology for more details.");
            }
        }
        else
        {
            LogMgr.log(LOG, LogLevel.PROCESSING1, "Call from " + SendUserInvitationFP.class + ". Account is already verified  for candidate :: ", companyUser);
        }
    }
    
    
    
    private Boolean isEmailFound(ObjectTransaction objTran, String email)
    {
        if(email!=null)
        {
            SecUser user    = SecUser.searchNAME(objTran, email.toLowerCase());
            
            if(user!=null) //&& user.getExtension(CompanyUser.REFERENCE_CompanyUser)!=null
            {
                return Boolean.TRUE;
            }
        }
        
        return Boolean.FALSE;
    }
}