package com.dla.dda.services;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import javax.xml.crypto.Data;

import org.hibernate.type.StringType;
import org.hibernate.type.Type;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.dla.dda.domain.constants.ErrorCodes;
import com.dla.dda.domain.exceptions.DLAIntegrationException;
import com.dla.dda.domain.exceptions.utils.ErrorUtils;
import com.dla.dda.domain.model.UserInfo;
import com.dla.dda.domain.model.request.SecurityRequest;
import com.dla.dda.domain.model.response.SecurityResponse;
import com.dla.dda.persistence.dao.BaseDAO;

/**
 * @see Data Service para los servicios que correspondan a seguridad
 * @author montieln
 *
 */
@Repository
public class SecurityService {

	@Autowired
	private BaseDAO dao;

	private static Logger logger = LoggerFactory.getLogger(EstudiosService.class);

	/**
	 * Metodo que hace la autenticacion con base al user y password
	 * 
	 * @param request
	 * @return
	 * @throws DLAIntegrationException
	 */
	public SecurityResponse login(SecurityRequest request) throws DLAIntegrationException {

		String username = request.getUser();
		String password = request.getPassword();

		Type[] types = { StringType.INSTANCE };

		Object[] params = new Object[types.length];
		params[0] = username;

		SecurityResponse response = new SecurityResponse();

		try {
			List<Object[]> rawResult = dao.findListByQuery("userExistDLA", params, types, Object[].class);

			// Si no existe el usuario en el sistema
			if (rawResult == null || rawResult.size() == 0) {
				logger.error("Usuario no existe [{}]", username);
				response.setEnabled(Boolean.FALSE);
				response.setDetail("Usuario No existe");
				return response;
			}

			Object[] result = rawResult.get(0);
			String expediente = (String) result[0];
			String pass = (String) result[1];
			String idArea = (String) result[3];
			String area = (String) result[4];
			String nombre = (String) result[5];
			String empresa = (String) result[6];
			String email = (String) result[7];
			
			UserInfo userInfo = new UserInfo();
			userInfo.setArea(area);
			userInfo.setEmail(email);
			userInfo.setEmpresa(empresa);
			userInfo.setNombreCompleto(nombre);
			userInfo.setUsername(username);

			// Si existe el usuario en el sistema pero no es el mismo password
			if (!pass.equals(password)) {

				logger.error("Password no valido [{}] [{}]", username, password);
				response.setEnabled(Boolean.FALSE);
				response.setDetail("Password no valido");
				return response;

			}

			Integer value = (result[1]) != null ? (((BigDecimal) result[2])).intValue() : 0;

			Boolean enabled = (value == 1) ? true : false;
			
			List<String> accesos = AccesosArea.from(new Integer(idArea).intValue()).getAccesos();
			
			response.setUsername(expediente);
			response.setEnabled(enabled);
			response.setPerfil(accesos);
			response.setUser(userInfo);

		} catch (IOException e) {

			logger.error("Error al Autenticar [{}] [{}] [{}]", username, password, e.getMessage(), e);
			ErrorCodes error = ErrorCodes.INFRASTRUCTURE;
			ErrorUtils.setMessage(error, e.getMessage());
			throw new DLAIntegrationException(error);

		}

		return response;
	}

	/**
	 * @see Metodo para traernos los perfiles de DDA
	 * @param request
	 * @return
	 * @throws DLAIntegrationException
	 */
	public SecurityResponse findPerfil(SecurityRequest request) throws DLAIntegrationException {

		String username = request.getUser();

		Type[] types = { StringType.INSTANCE };

		Object[] params = new Object[types.length];
		params[0] = username;

		SecurityResponse response = new SecurityResponse();

		try {
			List<Object[]> rawResult = dao.findListByQuery("findPerfilByUsername", params, types, Object[].class);

			List<String> perfiles = new ArrayList<>();

			for (Object[] result : rawResult) {
				String perfil = (String) result[1];
				perfiles.add(perfil);
			}

			response.setPerfil(perfiles);

		} catch (IOException e) {

			logger.error("Error al Obtener perfiles [{}] [{}]", username, e.getMessage(), e);
			ErrorCodes error = ErrorCodes.INFRASTRUCTURE;
			ErrorUtils.setMessage(error, e.getMessage());
			throw new DLAIntegrationException(error);

		}

		return response;
	}

}
