package sfs3.extensions.examples.signup;

import java.time.Year;
import java.util.Arrays;
import java.util.HashMap;

import com.smartfoxserver.components.login.ILoginAssistantPlugin;
import com.smartfoxserver.components.login.LoginAssistantComponent;
import com.smartfoxserver.components.login.LoginData;
import com.smartfoxserver.components.signup.ISignUpAssistantPlugin;
import com.smartfoxserver.components.signup.PasswordMode;
import com.smartfoxserver.components.signup.RecoveryMode;
import com.smartfoxserver.components.signup.SignUpAssistantComponent;
import com.smartfoxserver.components.signup.SignUpConfiguration;
import com.smartfoxserver.components.signup.SignUpErrorCodes;
import com.smartfoxserver.components.signup.SignUpValidationException;
import com.smartfoxserver.entities.User;
import com.smartfoxserver.entities.data.ISFSObject;
import com.smartfoxserver.extensions.SFSExtension;
import com.smartfoxserver.security.DefaultPermissionProfile;

public class SignUpExtension extends SFSExtension
{
	private SignUpAssistantComponent suac;
	private LoginAssistantComponent lac; 
	
	private static final class CustomValidator implements ISignUpAssistantPlugin
	{
		private final String zoneName;
		
		public CustomValidator(String zoneName)
        {
			this.zoneName = zoneName;
        }
		
		@Override
		public void execute(User user, ISFSObject params, SignUpConfiguration config) throws SignUpValidationException
		{
		    Integer birthYear = params.getInt("birth_year");
		    String country = params.getString("country");
		    
		    Integer age = birthYear != null ? Year.now().getValue() - birthYear : null;
		    
		    if (age == null || age < 5)
		    	throw new SignUpValidationException(SignUpErrorCodes.CUSTOM_ERROR, "Your age must be greater than 5 years old");
		    
		    if (country == null || country.length() < 2)
		    	throw new SignUpValidationException(SignUpErrorCodes.CUSTOM_ERROR, "Please enter your country");
		    
		    String message = "";
		    
		    if (age < 18) 
				message = "Since your age is below 18, in-game purchases will not be available";
			
		    HashMap<String, String> customMailFields = new HashMap<String, String>();
			customMailFields.put("${ageComment}", message);
			config.emailResponse.customEmailFields = customMailFields;	
		
		    // Add the Zone id
		    params.putString("zone", zoneName);
		    
		}
	}

	@Override
	public void init()
	{
		initSignUpAssistant();
		initLoginAssistant();
	}
	
	@Override
	public void destroy()
	{
	    super.destroy();
	    
	    lac.destroy();
	}
	
	private void initSignUpAssistant()
	{
		suac = new SignUpAssistantComponent();
		
		suac.getConfig().passwordMode = PasswordMode.SHA256;
		suac.getConfig().signUpTable = "accounts";
		suac.getConfig().extraFields = Arrays.asList("country", "birth_year", "zone");
		suac.getConfig().activationCodeField = "act_code";
		suac.getConfig().preProcessPlugin = new CustomValidator(getParentZone().getName());
		
		suac.getConfig().emailResponse.isActive = true;
		suac.getConfig().emailResponse.fromAddress = "someone@somewebsite.net";
		suac.getConfig().emailResponse.subject = "Thanks for signing up";
		suac.getConfig().emailResponse.template = "SignUpEmailTemplates/SignUpConfirmation.html";
		
		// Password recovery setup
		suac.getConfig().passwordRecovery.isActive = true;
		suac.getConfig().passwordRecovery.mode = RecoveryMode.GENERATE_NEW;
		suac.getConfig().passwordRecovery.email.fromAddress = "someone@somewebsite.net";
		suac.getConfig().passwordRecovery.email.subject = "Password recovery service";
		suac.getConfig().passwordRecovery.email.template = "SignUpEmailTemplates/PasswordRegen.html";
		
		addRequestHandler(SignUpAssistantComponent.COMMAND_PREFIX, suac);
	}
	
	private void initLoginAssistant()
	{
		lac = new LoginAssistantComponent(this);
		
		lac.getConfig().loginTable = "accounts";
		lac.getConfig().userNameField = "email";
		lac.getConfig().passwordField = "password";
		lac.getConfig().nickNameField = "username";
		lac.getConfig().activationField = "active";
		lac.getConfig().activationErrorMessage = "Your account has not been activated yet!";
		
		lac.getConfig().extraFields = Arrays.asList("country", "birth_year");
		
		lac.getConfig().postProcessPlugin = new ILoginAssistantPlugin()
		{
			@Override
			public void execute(LoginData loginData)
			{
				loginData.session.setProperty("$permission", DefaultPermissionProfile.STANDARD);
			}
		};
	}
}
