package com.uva.rafael.tfg_goniometer.view.fragments;

import android.app.Fragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;

import com.uva.rafael.tfg_goniometer.R;
import com.uva.rafael.tfg_goniometer.dependencyInjection.App;
import com.uva.rafael.tfg_goniometer.interfaces.ViewFunctions;
import com.uva.rafael.tfg_goniometer.presenter.NuevoPacientePresenter;

import javax.inject.Inject;

/**
 * Esta clase es el <tt>Fragment</tt> que se encarga de, cuando el usuario quiere añadir un nuevo
 * paciente a la Base de Datos, recoger toda la información que ha introducido éste, enviarla al
 * Presentador <tt>NuevoPacientePresenter</tt> y finalmente mostrar un mensaje indicando si se ha
 * añadido el paciente con éxito, o ha ocurrido algún error durante el proceso.
 *
 * <p>Esta clase forma parte de la aplicación TFG-Goniometer, desarrollada para el Trabajo de
 * Fin de Grado - Grado en Ingeniería Informática (Universidad de Valladolid)</p>
 *
 * @author Rafael Matamoros Luque
 * @see NuevoPacientePresenter
 * @version 1.0
 */

public class NuevoPacienteFragment extends Fragment implements ViewFunctions.NuevoPacienteFunctions {

    /*
     * Presentador asociado con este Fragment (Vista). Su instancia se obtiene mediante Inversión
     * de Dependencias
     */
    @SuppressWarnings({"unused", "CanBeFinal"})
    @Inject
    NuevoPacientePresenter presenter;

    /**
     * Método llamado para instanciar el <tt>Fragment</tt> con su layout asociada
     * (R.layout.nuevo_paciente_fragment, en este caso).
     * <p>
     * Se encarga, simplemente, de recoger la información introducida por el usuario y enviarla a
     * <tt>NuevoPacientePresenter</tt> cuando éste pulse sobre el botón "GUARDAR".
     *
     * @param inflater The LayoutInflater object that can be used to inflate any view in the
     *                 fragment.
     * @param container If non-null, this is the parent view that the fragment's UI should be
     *                  attached to. The fragment should not add the view itself, but this can be
     *                  used to generate the LayoutParams of the view.
     * @param savedInstanceState If non-null, this fragment is being re-constructed from a previous
     *                           saved state as given here. Return the View for the fragment's UI,
     *                           or null.
     */
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {

        // Obtención de la instancia de NuevoPacientePresenter
        ((App) getActivity().getApplication()).getComponent(this).injectNuevoPacienteFragment(this);

        // Inflar el layout del Fragment
        View vista = inflater.inflate(R.layout.nuevo_paciente_fragment, container, false);

        /*
         * Variables locales que se bindearán con los EditText y RadioGroup del layout para recoger
         * la información introducida por el usuario
         */
        final EditText nombre, edad, id, telefono, direccion, sintomas, diagnostico,
                tratamiento_previo, tratamiento_actual, comentarios_adicionales, tags;

        final RadioGroup sexo;

        // Bindeo de las variables con los elementos del layout
        nombre = (EditText) vista.findViewById(R.id.nombre_editText);
        edad = (EditText) vista.findViewById(R.id.edad_editText);
        id = (EditText) vista.findViewById(R.id.id_editText);
        telefono = (EditText) vista.findViewById(R.id.telefono_editText);
        direccion = (EditText) vista.findViewById(R.id.direccion_editText);
        sintomas = (EditText) vista.findViewById(R.id.sintomas_editText);
        diagnostico = (EditText) vista.findViewById(R.id.diagnostico_editText);
        tratamiento_previo = (EditText) vista.findViewById(R.id.tratamiento_previo_editText);
        tratamiento_actual = (EditText) vista.findViewById(R.id.tratamiento_actual_editText);
        comentarios_adicionales = (EditText) vista.findViewById(R.id.comentarios_adicionales_editText);
        tags = (EditText) vista.findViewById(R.id.tags_editText);

        sexo = (RadioGroup) vista.findViewById(R.id.sexoRadioGroup);

        // Bindeo del botón "GUARDAR"
        vista.findViewById(R.id.guardar_paciente).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                /*
                 * Cuando el usuario pulsa el botón, toda la información introducida es enviada a
                 * NuevoPacientePresenter para que compruebe si es correcta y, de ser así,
                 * almacenarla en la BD
                 */
                presenter.onSaveClicked(nombre.getText().toString(),
                        edad.getText().toString(),
                        sexo.getCheckedRadioButtonId(),
                        id.getText().toString(),
                        telefono.getText().toString(),
                        direccion.getText().toString(),
                        sintomas.getText().toString(),
                        diagnostico.getText().toString(),
                        tratamiento_previo.getText().toString(),
                        tratamiento_actual.getText().toString(),
                        comentarios_adicionales.getText().toString(),
                        tags.getText().toString());
            }
        });
        return vista;
    }

    /**
     * Método que muestra un mensaje de éxito cuando se ha logrado almacenar correctamente un
     * paciente en la Base de Datos.
     */
    @Override
    public void displaySuccess() {
        Toast toast = Toast.makeText(getActivity(), R.string.patient_success,
                Toast.LENGTH_LONG);

        TextView textView = (TextView) toast.getView().findViewById(android.R.id.message);

        if (textView != null)
            textView.setGravity(Gravity.CENTER); // Centrar el mensaje en el Toast

        toast.show();
    }

    /**
     * Método que muestra un mensaje de error cuando se ha intentado introducir un nuevo paciente
     * en la Base de Datos.
     */
    @Override
    public void displayErrorDatabase() {
        Toast toast = Toast.makeText(getActivity(), R.string.patient_error_database,
                Toast.LENGTH_LONG);

        TextView textView = (TextView) toast.getView().findViewById(android.R.id.message);

        if (textView != null)
            textView.setGravity(Gravity.CENTER); // Centrar el mensaje en el Toast

        toast.show();
    }

    /**
     * Método que muestra un mensaje de error cuando el usuario ha introducido algún dato erróneo, o
     * no ha rellenado alguno de los campos obligatorios al almacenar un nuevo paciente.
     */
    @Override
    public void displayErrorUser() {
        Toast toast = Toast.makeText(getActivity(), R.string.user_error,
                Toast.LENGTH_LONG);

        TextView textView = (TextView) toast.getView().findViewById(android.R.id.message);

        if (textView != null)
            textView.setGravity(Gravity.CENTER); // Centrar el mensaje en el Toast

        toast.show();
    }

    /**
     * Método que muestra un mensaje de error cuando el usuario ha intentado introducir un paciente
     * con el mismo nombre e ID que uno ya existente en la Base de Datos.
     */
    @Override
    public void displayErrorExistingPatient() {
        Toast toast = Toast.makeText(getActivity(), R.string.existing_patient_error,
                Toast.LENGTH_LONG);

        TextView textView = (TextView) toast.getView().findViewById(android.R.id.message);

        if (textView != null)
            textView.setGravity(Gravity.CENTER); // Centrar el mensaje en el Toast

        toast.show();
    }

    /**
     * Perform any final cleanup before an activity is destroyed.
     */
    @Override
    public void onDestroy() {
        presenter.onDestroy();
        super.onDestroy();
    }
}
