package com.ejie.ab79.rest.serviciosWeb;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.ejie.ab79.comun.Constantes;
import com.ejie.ab79.comun.UtilsConfig;
import com.ejie.ab79.exceptions.Ab79Exception;
import com.ejie.ab79.model.Inspectores;
import com.ejie.ab79.model.REST.servicioWeb.GenericResponse;
import com.ejie.ab79.model.REST.servicioWeb.UsuarioWS;
import com.ejie.ab79.rest.util.AuthenticationUtil;
import com.ejie.ab79.service.InspectoresService;
import com.fasterxml.jackson.core.JsonProcessingException;

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

/**
 * 
 *  
 *
 */
@Controller()
@RequestMapping(value = "/user", produces = Constantes.APPLICATION_JSON_UTF8_VALUE)
public class UserController {
	
	@Resource
	ReloadableResourceBundleMessageSource appMessageSource;
	
	@Autowired()
	private InspectoresService inspectoresService;
	
	/**
	 * Capturamos los JSON que no se pueden capturar en los métodos.
	 * 
	 * @param request HttpServletRequest
	 * @param response HttpServletResponse
	 * @param e HttpMessageNotReadableException
	 * @return GenericResponse
	 */
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public @ResponseBody() GenericResponse handle400(HttpServletRequest request, HttpServletResponse response, HttpMessageNotReadableException e) {
		response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
    	String error = "error.400";
    	
		return new GenericResponse(Constantes.ENVIO_JSON_ESTADO_ERROR, error,
				this.appMessageSource.getMessage(error, null, new Locale("es")),
				this.appMessageSource.getMessage(error, null, new Locale("eu")));
    }
    
	/**
	 * Clase que implementa el proceso de autenticación mediante un login usuario/contraseña
	 * @param username
	 * @param pwd
	 * @return
	 * @throws JsonProcessingException 
	 */
	@RequestMapping(value = "/login", method = RequestMethod.POST)
	public @ResponseBody() Object login(HttpServletResponse response, @RequestBody() UsuarioWS usuario)  throws Ab79Exception, JsonProcessingException {	
		
		/***************************************************************
		 * Para que funcionen las trazas de UDA 
		 * Es necesario crear en el contexto de la aplicacion el usuario
		 * **************************************************************/
//		AuthenticationUtil.addAuthentication(usuario.getUser(), "N/A", "N/A", "ROLE_USER");
		
		/*************************************************************************/

		
		
		/******************************************************************************
		 * Validar si usuario y contraseña existe en la tabla AB7904T00 (Inspectores)
		 * ****************************************************************************/
		Inspectores inspectores = new Inspectores();
		inspectores.setUsuarioXlnets(usuario.getUser());
		inspectores.setPasswordTablet(usuario.getPassword());		
		List<Inspectores> listaInspectores= inspectoresService.findAll(inspectores, null);
		
		if (listaInspectores.size() > 0){
			
			if (listaInspectores.get(0).getUsuarioXlnets()!= null  && listaInspectores.get(0).getPasswordTablet() != null){
			
				if ( listaInspectores.get(0).getUsuarioXlnets().equals(usuario.getUser()) &&  listaInspectores.get(0).getPasswordTablet().equals(usuario.getPassword())){
					Map<String, String> loginResult = new HashMap<String, String>();
					AuthenticationUtil.addAuthentication(listaInspectores.get(0).getIdInspector(), usuario.getUser(), "N/A", "N/A", "ROLE_USER");
					
					String token = getJWTToken(listaInspectores.get(0).getIdInspector(), usuario.getUser());
					loginResult.put("authorization", token);
					
					return loginResult;
					
				}else{
					response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
					String sCodigoError = "error.usuarioyPassword";
					return new GenericResponse(Constantes.ENVIO_JSON_ESTADO_ERROR, "error.usuarioyPassword", appMessageSource.getMessage(sCodigoError, null, new Locale("es")), appMessageSource.getMessage(sCodigoError, null, new Locale("eu")));
				}
			}else{
				response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
				String sCodigoError = "error.usuarioyPassword";
				return new GenericResponse(Constantes.ENVIO_JSON_ESTADO_ERROR, "error.usuarioyPassword", appMessageSource.getMessage(sCodigoError, null, new Locale("es")), appMessageSource.getMessage(sCodigoError, null, new Locale("eu")));
			}
		}else{
			response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
			String sCodigoError = "error.usuarioyPassword";
			return new GenericResponse(Constantes.ENVIO_JSON_ESTADO_ERROR, "error.usuarioyPassword", appMessageSource.getMessage(sCodigoError, null, new Locale("es")), appMessageSource.getMessage(sCodigoError, null, new Locale("eu")));
		}
		
		/********************************************************************************/
	}

	/**
	 * Metodo que construye el token 
	 * @param username
	 * @return
	 */
	private String getJWTToken(Integer id, String username) {
		
		long tiemnpoExpiracionToken =Long.parseLong(UtilsConfig.getAppProperties().getProperty("TIEMPO_VALIDEZ_TOKEN"));
		String secretKey = "ab79BM";
		
		
		String token = Jwts.builder()				
				.setId(id.toString())
				.setSubject(username)
				.setIssuedAt(new Date(System.currentTimeMillis()))
				.setExpiration(new Date(System.currentTimeMillis() + tiemnpoExpiracionToken))
				.signWith(SignatureAlgorithm.HS512,
						secretKey.getBytes()).compact();
		
		
	
		return "Bearer " + token;
	}
}
