package pfc.android.gestormensajeria.activities;

import java.util.HashMap;
import java.util.Map;

import pfc.android.gestormensajeria.R;
import pfc.android.gestormensajeria.dao.GestorMensajeriaDAO;
import pfc.android.gestormensajeria.entidades.ComponenteGrupo;
import pfc.android.gestormensajeria.entidades.Grupo;
import pfc.android.gestormensajeria.parametros.ParametrosNavegacion;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;

/**
 * Activity para la gestión y uso de Grupos de destinatarios de mensajes SMS
 * @author Francisco Joseé Lamela Rincón
 *
 */
public class GruposActivity extends Activity {

	/**
	 * Colección que usaremos para trabajar con los grupos
	 */
	private Map<String, Grupo> grupos = null;
	
	/**
	 * Colección que usaremos para trabajar con los componentes de cada grupo
	 */
	private Map<String, ComponenteGrupo> componentesGrupo = null;
	
	/**
	 * Propiedad de tipo Grupo que usaremos para controlar el grupo seleccionado en cada momento
	 */
	private Grupo grupoSeleccionado = null;

	/**
	 * Propiedad de tipo ComponenteGrupo que usaremos para controlar el componente del grupo seleccionado en cada momento
	 */
	private ComponenteGrupo componenteGrupoSeleccionado = null;

	/**
	 * Propiedad que usaremos para el control de la lista de grupos que se muestra en la Activity
	 */
	private ListView lstGrupos = null;
	
	/**
	 * Array con los nombres de los grupos que usaremos para montar la lista en pantalla
	 */
	private String[] nombresGrupos = null;
	
	/**
	 * Propiedad de tipo ArrayAdapter para controlar el adaptador usado para mostrar y gestionar la lista de grupos mostrada en pantalla
	 */
	private ArrayAdapter<String> adapterGrupos = null;
	
	/**
	 * Propiedad que usaremos para el control de la lista de contactos de cada grupo que se muestra en la Activity
	 */
	private ListView lstComponentesGrupo = null;
	
	/**
	 * Array con los nombres de los componentes de cada grupo que usaremos para montar la lista en pantalla
	 */
	private String[] nombresComponentesGrupos = null;
	
	/**
	 * Propiedad de tipo ArrayAdapter para controlar el adaptador usado para mostrar y gestionar la lista de componentes de grupo mostrada en pantalla
	 */
	private ArrayAdapter<String> adapterComponentesGrupo = null;

	
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_grupos);
		
		//Obtenemos los grupos registrados en el sistema
		obtenerGrupos();
		
		//Generamos las estructura de la lista de grupos para mostrarla en pantalla
		lstGrupos = (ListView)findViewById(R.id.lstNombresGrupos);
		adapterGrupos = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, nombresGrupos);
		lstGrupos.setAdapter(adapterGrupos);
		lstGrupos.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> list, View view, int pos, long id) {
            	onGrupoSeleccionado(grupos.get(nombresGrupos[pos]));
            }
        });
		
		//Generamos las estructura de la lista de componentes de grupo para mostrarla en pantalla
		lstComponentesGrupo = (ListView)findViewById(R.id.lstContactosEnGrupo);
		adapterComponentesGrupo = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, nombresComponentesGrupos);
		lstComponentesGrupo.setAdapter(adapterComponentesGrupo);
		lstComponentesGrupo.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> list, View view, int pos, long id) {
            	onComponenteGrupoSeleccionado(nombresComponentesGrupos[pos]);
            }
        });

        //Establecemos el comportamiento ante los eventos onclick en los distintos botones que se muestran en la pantalla
		establecerEventosOnClick();
		
		//Aseguramos que el nombre del grupo esté deshabilitado
		activarDesactivarNombreGrupo(false);
	}

	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		
		//Comprobamos si el resultado es el esperado
		if(resultCode == ParametrosNavegacion.CONTACTO_OK){
			//Obtenemos el valor
			Bundle b = data.getExtras();
			Integer idContacto = b.getInt(ParametrosNavegacion.CONTACTO_ID);
	        String nombreContacto = b.getString(ParametrosNavegacion.CONTACTO_NOMBRE);
	        
	        //Obtenemos el nombre del grupo
	        String nombreGrupo = null;
	        
	        //Si no hay grupo seleccionado es que es uno nuevo y lo cogemos del campo editable, si ya hay grupo seleccionado lo cogemos directamente de ahí
	        if(grupoSeleccionado == null){
	        	//Obtenemos el nombre desde el campo
	        	EditText editNombreGrupo = (EditText)findViewById(R.id.editNombreGrupoGestion);
	        	nombreGrupo = editNombreGrupo.getText().toString();
	        	
	        	//Cremos un nuevo grupo
	        	grupoSeleccionado = new Grupo(nombreGrupo);

	        	//Actualizamos las colecciones
	        	if(!grupos.containsKey(nombreGrupo)){
	        		grupos.put(nombreGrupo, grupoSeleccionado);
	        		nombresGrupos = new String[grupos.size()];
	    			int indiceGrupos = 0;
	    			for(String nomGrupo: grupos.keySet()){
	    				nombresGrupos[indiceGrupos] = nomGrupo; 
	    				indiceGrupos++;
	    			}
	    			
	    			//Refrescamos la lista de grupos
	    			adapterGrupos = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, nombresGrupos);
	    			lstGrupos.setAdapter(adapterGrupos);
	        	}
	        }else
	        	nombreGrupo = grupoSeleccionado.getNombre();
	        	

	        //Registramos el nuevo componente de grupo en BD y lo añadimos al grupo
	        ComponenteGrupo cg = GestorMensajeriaDAO.guardarComponenteGrupo(this, nombreGrupo, idContacto, nombreContacto);
	        if(cg != null){
	        	grupoSeleccionado.incluirDestinatario(cg);
	        	actualizarListaDestinatarios(false);
	        	
				//Deshabilitamos el nombre del grupo para que no se pueda editar
				activarDesactivarNombreGrupo(false);
	        }else
	        	Toast.makeText(GruposActivity.this.getApplicationContext(), R.string.toast_error_guardar_nuevo_componente_grupo, Toast.LENGTH_LONG).show();
		}			
	}
	

	// ***********************  METODOS AUXILIARES  ***********************
	
	/**
	 * Metodo que obtiene todos los grupos de destinatarios definidos en el sistema
	 * @return boolean true si la consulta se ha relizado correctamente y ha devuelto resultados, o false en cualquier otro caso
	 */
	private boolean obtenerGrupos(){
		boolean ok = false;
		
		//Obtenemos los grupos
		grupos = GestorMensajeriaDAO.getGrupos(this);
			
		//Si hay resultados se rellenan las colecciones correspondientes para manejar la información y mostrar el listado de grupos
		if(grupos != null && grupos.size() > 0){
			ok = true;
			nombresGrupos = new String[grupos.size()];
			int indiceGrupos = 0;
			for(String nombreGrupo: grupos.keySet()){
				nombresGrupos[indiceGrupos] = nombreGrupo; 
				indiceGrupos++;
			}
				
		}//Si no hay resultados se inicializa la coleccion que se muestra en la lista
		else
			nombresGrupos = new String[0];
		
		//Actualizamos la lista que muestra los contactos de los grupos 
		actualizarListaDestinatarios(false);
		
		return ok;
	}
	
	
	/**
	 * Actualiza la lista de destinatarios (ComponentesGrupo) del grupo seleccionado y reinicia el destinatario seleccionado
	 * @param soloLimpiar
	 */
	private void actualizarListaDestinatarios(boolean soloLimpiar) {
		//Si no hay grupo seleccionado o estamos limpiando, vaciamos las colecciones con las que gestionamos la lista de destinatarios
		if(grupoSeleccionado == null || soloLimpiar){
			nombresComponentesGrupos = new String[0];
			if(componentesGrupo == null)
				componentesGrupo = new HashMap<String, ComponenteGrupo>();
			else
				componentesGrupo.clear();

		}//Si no estamos limpiando y hay un grupo seleccionado, cargamos los componentes del grupo en la lista
		else{
			//Inicializamos las colecciones
			componentesGrupo = new HashMap<String, ComponenteGrupo>();
			nombresComponentesGrupos = new String[grupoSeleccionado.getDestinatarios().size()];
			
			//Recorremos los destinatarios del grupo y rellenamos las colecciones con los valores adecuados
			int indiceComponentes = 0;
			for(ComponenteGrupo cg: grupoSeleccionado.getDestinatarios()){
				nombresComponentesGrupos[indiceComponentes] = cg.getNombreDestinatario(); 
				componentesGrupo.put(cg.getNombreDestinatario(), cg);
				indiceComponentes++;
			}
		}
		
		//Inicializamos el contacto seleccionado
		componenteGrupoSeleccionado = null;

		//Refresecamos la lista de destinatarios
		adapterComponentesGrupo = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, nombresComponentesGrupos);
		lstComponentesGrupo = (ListView)findViewById(R.id.lstContactosEnGrupo);
		lstComponentesGrupo.setAdapter(adapterComponentesGrupo);
	}
	
	
	/**
	 * Establece el comportamiento ante los eventos onclick en los distintos botones que se muestran en la pantalla
	 */
	private void establecerEventosOnClick() {
		//Establecemos el comportamiento al pulsar sobre el boton de incluir contacto
		final View cvIncluirContacto = findViewById(R.id.btnIncluirContactoGrupos);
		cvIncluirContacto.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View view) {
				//Comprobamos si tiene sentido un click sobre este boton, es decir, si se esta editando o creando uno nuevo
				EditText cvNombreGrupo = (EditText)findViewById(R.id.editNombreGrupoGestion);
				if(cvNombreGrupo.getText() == null || cvNombreGrupo.getText().length() == 0){
					if(cvNombreGrupo.isEnabled())
						Toast.makeText(GruposActivity.this.getApplicationContext(), R.string.toast_error_falta_nombre_nuevo_grupo, Toast.LENGTH_LONG).show();
					else
						Toast.makeText(GruposActivity.this.getApplicationContext(), R.string.toast_error_falta_no_nuevo_ni_edicion, Toast.LENGTH_LONG).show();
				}else{//Si es correcta la pulsación, navegamos a la pantalla de selección de contacto
					//Creamos el Intent
	                Intent intent = new Intent(GruposActivity.this, ListaContactosActivity.class);
	                
	                //Preparamos la informacion a pasar, en este caso los ids de los contactos ya incluidos para que no nos muestre los que ya tenemos
	                String idsContactos = null;
	                if(grupoSeleccionado != null){
	                	idsContactos = "";
	                	boolean primero = true;
	                	for(ComponenteGrupo cg: grupoSeleccionado.getDestinatarios()){
	                		if(primero){
	                			idsContactos += cg.getIdDestinatario();
	                			primero = false;
	                		}else
	                			idsContactos += "," + cg.getIdDestinatario();
	                	}
	                }
	                
	                //Creamos la información a pasar entre actividades
	                Bundle b = new Bundle();
	                b.putString(ParametrosNavegacion.IDS_CONTACTOS_INCLUIDOS, idsContactos);

	                //Añadimos la información al intent
	                intent.putExtras(b);

	                //Iniciamos la nueva actividad
	                startActivityForResult(intent, ParametrosNavegacion.CONTACTO_OK);
				}
			}
		});
		
		
		//Establecemos el comportamiento al pulsar sobre el boton de borrar contacto
		final View cvQuitarContacto = findViewById(R.id.btnQuitarContacto);
		cvQuitarContacto.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View view) {
				
				if(componenteGrupoSeleccionado == null)
					Toast.makeText(GruposActivity.this.getApplicationContext(), R.string.toast_error_contacto_no_seleccionado, Toast.LENGTH_LONG).show();
				else{
					//Quitamos el contacto del grupo
					grupoSeleccionado.getDestinatarios().remove(componenteGrupoSeleccionado);
					
					//Eliminamos el registro en bd
					GestorMensajeriaDAO.borrarComponenteGrupo(GruposActivity.this, componenteGrupoSeleccionado.getId());
					
					actualizarListaDestinatarios(false);
				}
			}
		});
		
		
		//Establecemos el comportamiento al pulsar sobre el boton de nuevo grupo
		final View cvNuevoGrupo = findViewById(R.id.btnNuevoGrupo);
		cvNuevoGrupo.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View view) {
				//Inicializamos el grupo seleccionado
				grupoSeleccionado = null;
				
				//Limpiamos los campos
				activarDesactivarNombreGrupo(true);
				
				//Limpiamos la lista de contactos del grupo 
				actualizarListaDestinatarios(true);
			}
		});

		
		//Establecemos el comportamiento al pulsar sobre el boton de usar grupo
  		final View btnUsarGrupo = findViewById(R.id.btnUsarGrupo);
  		btnUsarGrupo.setOnClickListener(new View.OnClickListener() {
  			@Override
  			public void onClick(View view) {
  				if(grupoSeleccionado != null){
  					//Creamos el Intent
  	                Intent intent = new Intent();
  	                //Creamos la información a pasar entre actividades
  	                Bundle b = new Bundle();
  	                b.putString(ParametrosNavegacion.GRUPO_DESTINATARIOS, grupoSeleccionado.getNombre());
  	                //Añadimos la información al intent
  	                intent.putExtras(b);
  	                setResult(ParametrosNavegacion.GRUPO_OK, intent);
  	                finish();
  				}else
  					Toast.makeText(GruposActivity.this.getApplicationContext(), R.string.toast_error_usar_grupo, Toast.LENGTH_LONG).show();
  			}
  		});
  		
  		
  		//Establecemos el comportamiento al pulsar sobre el boton de borrar grupo
  		final View btnBorrarGrupo = findViewById(R.id.btnBorrarGrupo);
  		btnBorrarGrupo.setOnClickListener(new View.OnClickListener() {
  			@Override
  			public void onClick(View view) {
  				if(grupoSeleccionado != null){
  					borrarGrupo();
  				}else
  					Toast.makeText(GruposActivity.this.getApplicationContext(), R.string.toast_error_usar_grupo, Toast.LENGTH_LONG).show();
  			}
  		});
	}


	/**
	 * Habilita o deshabilita el campo del nombre de grupo en función del parámetro activar
	 * @param activar
	 */
	private void activarDesactivarNombreGrupo(boolean activar){
		//Obtenemos el control para el nombre del grupo y damos valor a su propiedad enabled
		final View cvNombreGrupo = findViewById(R.id.editNombreGrupoGestion);
		cvNombreGrupo.setEnabled(activar);
		//Si estamos creando uno nuevo limpiamos el control
		if(activar)
			((EditText)cvNombreGrupo).getText().clear();
			
	}
	

	/**
	 * Actualiza la lista de destinatarios y el nombre del grupo a partir del grupo seleccionado.
	 * @param grupo
	 */
	private void onGrupoSeleccionado(Grupo grupo) {
		grupoSeleccionado = grupo;
		
		EditText editNombreGrupo = (EditText)findViewById(R.id.editNombreGrupoGestion);
		editNombreGrupo.setText(grupo.getNombre());
		 
		actualizarListaDestinatarios(false);
	}
	
	
	/**
	 * Actualiza el componente de grupo seleccionado
	 * @param nombreContacto
	 */
	private void onComponenteGrupoSeleccionado(String nombreContacto) {
		componenteGrupoSeleccionado = componentesGrupo.get(nombreContacto);
	}
	
	/**
	 * Pregunta si se desea borrar la plantilla seleccionada y establece el comportamiento para cada uno de los casos afirmativo o negativo. 
	 */
	private void borrarGrupo(){
		//Comprobamos que se haya seleccionado un grupo para borrar
		if(grupoSeleccionado != null){
			//Borramos el registro con confirmación
	        AlertDialog.Builder dialogEliminar = new AlertDialog.Builder(this);
	        dialogEliminar.setIcon(android.R.drawable.ic_dialog_alert);
	        dialogEliminar.setTitle(getResources().getString(R.string.toast_titulo_eliminar_grupo));
	        dialogEliminar.setMessage(getResources().getString(R.string.toast_mensaje_eliminar_grupo));
	        dialogEliminar.setCancelable(false);
	       
	        //Establece el comportamiento cuando se responde afirmativamente
	        dialogEliminar.setPositiveButton(getResources().getString(android.R.string.ok), new DialogInterface.OnClickListener() {
	        	public void onClick(DialogInterface dialog, int boton) {
	        		//Borramos el grupo de BD
		        	GestorMensajeriaDAO.borrarGrupo(GruposActivity.this, grupoSeleccionado);
		            
		        	//Informamos al usuario de la finalizacion del procesos
		        	Toast.makeText(GruposActivity.this, R.string.toast_confirmacion_eliminar_grupo, Toast.LENGTH_SHORT).show();
		            
		            //Actualizamos las colecciones
		        	if(grupos.containsKey(grupoSeleccionado.getNombre())){
		        		grupos.remove(grupoSeleccionado.getNombre());
		        		nombresGrupos = new String[grupos.size()];
		    			int indiceGrupos = 0;
		    			for(String nomGrupo: grupos.keySet()){
		    				nombresGrupos[indiceGrupos] = nomGrupo; 
		    				indiceGrupos++;
		    			}
		        	}
		            
		            refrescarListaGrupos();
		            actualizarListaDestinatarios(true);
	        	}

	        });

	        //Establece el comportamiento cuando se responde negativamente
	        dialogEliminar.setNegativeButton(android.R.string.no, null);
	       
	        //Muestra el diálogo
	        dialogEliminar.show();	
		}
    }
	
	/**
	 * Refresca la lista de plantillas para que se muestren los cambios
	 */
	private void refrescarListaGrupos(){
		adapterGrupos = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, nombresGrupos);
		lstGrupos.setAdapter(adapterGrupos);
	}
	
}
