package performa.orm;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import oneit.logging.LogLevel;
import oneit.logging.LogMgr;
import oneit.logging.LoggingArea;
import oneit.objstore.*;
import oneit.objstore.rdbms.filters.EqualsFilter;
import oneit.security.SecUser;
import oneit.security.jsp.SecUserToNameTransform;
import oneit.utils.*;
import oneit.utils.parsers.FieldException;
import performa.orm.types.RoleType;
import performa.utils.Utils;


public class CompanyUser extends BaseCompanyUser
{
    private static final long serialVersionUID = 0L;
        
    public  static LoggingArea  LOG                 =   LoggingArea.createLoggingArea("CompanyUser");
    public  static final String DEFAULT_PASSWORD    =   "Talentology123";

    // This constructor should not be called
    public CompanyUser ()
    {
        // Do not add any code to this, always put it in initialiseNewObject
    }
    
    
    public static CompanyUser getCompanyUserForForgotPassword(ObjectTransaction transaction, String userIDStr, String code)
    {
        userIDStr   =   StringUtils.subBlanks(userIDStr);
        code        =   StringUtils.subBlanks(code);
        
        if(userIDStr != null && code!=null)
        {
            CompanyUser companyUser =   CompanyUser.getCompanyUserByID(transaction, Long.parseLong(userIDStr));
                        
            if(companyUser != null && CollectionUtils.equals(companyUser.getForgotPasswordKey(), code))
            {
                return companyUser;
            }
        }
        
        return null;
    }

    
    @Override
    public String getToString() 
    {
        return SecUserToNameTransform.INSTANCE.transform(getUser());
    }

    
    @Override
    protected void postRoleChange() throws FieldException 
    {
        SecUser secUser =   getUser();
        
        if(getRole()==RoleType.ADMIN)
        {
            if(secUser.hasRole(Utils.ROLE_COMPANY_USER))
            {
                secUser.removeRole(Utils.getRole(Utils.ROLE_COMPANY_USER, getTransaction()));
            }
            
            secUser.addRole(Utils.getRole(Utils.ROLE_COMPANY_ADMIN, getTransaction()));
            
            setRoleTypes(RoleType.ADMIN);
            removeRoleTypes(RoleType.STANDARD);
        }
        else if(getRole()==RoleType.STANDARD)
        {
            if(secUser.hasRole(Utils.ROLE_COMPANY_ADMIN))
            {
                secUser.removeRole(Utils.getRole(Utils.ROLE_COMPANY_ADMIN, getTransaction()));
            }
            
            secUser.addRole(Utils.getRole(Utils.ROLE_COMPANY_USER, getTransaction()));
            
            setRoleTypes(RoleType.STANDARD);
            removeRoleTypes(RoleType.ADMIN);
        }
        
        super.postRoleChange();
    }

    
    public void setRoleTypes(RoleType... roleType) throws FieldException
    {
        Set<RoleType> roles =   getRoles() != null ? getRoles() : new HashSet();
        
        roles.addAll(Arrays.asList(roleType));
        
        setRoles(roles);
    }
    
    
    public void removeRoleTypes(RoleType... roleType) throws FieldException
    {
        Set<RoleType> roles =   getRoles();
        
        if(roles != null)
        {
            roles.removeAll(Arrays.asList(roleType));
        
            setRoles(roles);
        }
    }
    
    
    @Override
    public FieldWriteability getWriteability_Role() 
    {
        if(CollectionUtils.equals(getCompany().getAddedByUser(),this))
        {
            return FieldWriteability.NOT_IN_GUI;
        }
        
        return super.getWriteability_Role();
    }
    
    
    public String getEmailAddressFromUser()
    {
        return  StringUtils.isEmailAddress(getUser().getUserName()) ? getUser().getUserName() : getUser().getEmail();
    }
    
    
    public Boolean isLoggedViaSocial()
    {
        return !StringUtils.isEmailAddress(getUser().getUserName());
    }
    
    
    //verfy and cahnge email
    public void changeEmail(HttpServletRequest  request) throws FieldException
    {
        if(getIsEmailChanged()==Boolean.TRUE)
        {
            if(request.getSession().getAttribute("EmailToVerify")!=null)
            {
                if(CollectionUtils.equals(request.getSession().getAttribute("EmailToVerify"), getUser()))
                {
                    setIsEmailChanged(Boolean.FALSE);

                    if(!isLoggedViaSocial())
                    {
                        SecUser   secUser   =  getUser();           

                        secUser.setUserName(secUser.getEmail());

                        LogMgr.log(LoggingArea.ALL, LogLevel.PROCESSING2, "User name changed.", secUser);
                    }
                    
                    request.getSession().setAttribute("EmailVerified", true);

                    LogMgr.log(LoggingArea.ALL, LogLevel.PROCESSING1, "User Email verified", this);
                }
                else
                {
                    request.getSession().setAttribute("EmailStillNotVerified", true);
                }
                
                request.getSession().removeAttribute("EmailToVerify");
            }
            else 
            {
                request.getSession().setAttribute("EmailStillNotVerified", true);
            }
        }
    }
    
    
    public boolean hasRole(RoleType role)
    {
        return getRoles() != null && getRoles().contains(role);
    }
    
    public boolean isOwner()
    {
        return pipelineCompanyUser().toHiringTeams().toRole().uniqueVals().contains(RoleType.OWNER);
    }
    
    
    public HiringTeam getActiveHiringTeam()
    {
        return getSelectedTeam() != null ? getSelectedTeam() : getDefaultHiringTeam();
    }
    

    @Override
    public HiringTeam getSelectedTeam() throws StorageException 
    {
        return super.getSelectedTeam() == null ? getDefaultHiringTeam() : super.getSelectedTeam();
    }
    
        
    public boolean showPrivacyPolicyAgreed()
    {
        return isTrue(getPrivacyPolicyAgreed());
    }
    
    public boolean showConditionsAgreed()
    {
        return isTrue(getConditionsAgreed());
    }
    
    public RoleType getRoleForHiringTeam(HiringTeam hiringTeam)
    {
        CompanyUserHiringTeamLink link = hiringTeam.pipelineHiringTeam().toUsers(CompanyUserHiringTeamLink.SearchByAll().andCompanyUser(new EqualsFilter<>(this))).val();
        return link != null ? link.getRole() : null;
    }
}