package logica;

import org.orm.PersistentException;
import orm.*;

import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Search {
    private static SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");


    //Actividad

    /**
     * Busca una actividad especifica en el sistema
     *
     * @param asignatura Asignatura a la que pertenece
     * @param fecha      fecha en la cual se realizara la actividad
     * @param tipo       el tipo de actividad
     * @return retorna la actividad si la encuentra, si no retorna un null.
     */
    public static Actividad buscarActividad(Asignatura asignatura, Date fecha, String tipo) {
        if (asignatura != null && fecha != null && tipo != null) {
            String query = "fecha = '" + format.format(fecha) + "' AND asignatura_id_fk=" + asignatura.getId_pk() + "AND tipo = '" + tipo + "'";
            try {
                Actividad[] actividades = ActividadDAO.listActividadByQuery(query, null);
                if (actividades.length > 0) {
                    return actividades[0];
                } else {
                    return null;
                }
            } catch (PersistentException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * Busca la lista de actividades que pertencen a una asignatura
     *
     * @param asignatura Asignatura a la que pertenecen
     * @return la lista de actividades, si es que encuentra, si no retornara un null.
     */
    public static Actividad[] buscarActividades(Asignatura asignatura) {
        if (asignatura != null) {
            String query = "asignatura_id_fk=" + asignatura.getId_pk();
            try {
                Actividad[] actividades = ActividadDAO.listActividadByQuery(query, "fecha");
                if (actividades.length > 0) {
                    return actividades;
                } else {
                    return null;
                }
            } catch (PersistentException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * Busca la lista de actividades en una fecha especifica
     *
     * @param fecha fecha a la cual pertenecen
     * @return la lista de actividades, si es que encuentra, si no retornara un null.
     */
    public static Actividad[] buscarActividades(Date fecha) {
        if (fecha != null) {
            String query = "fecha = '" + format.format(fecha) + "'";
            try {
                Actividad[] actividades = ActividadDAO.listActividadByQuery(query, "fecha");
                if (actividades.length > 0) {
                    return actividades;
                } else {
                    return null;
                }
            } catch (PersistentException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * Busca una lista de actividades segun su tipo.
     *
     * @param tipo tipo al que pertenecen
     * @return la lista de actividades, si es que encuentra, si no retornara un null.
     */
    public static Actividad[] buscarActividades(String tipo) {
        if (tipo != null) {
            String query = "tipo = '" + tipo + "'";
            try {
                Actividad[] actividades = ActividadDAO.listActividadByQuery(query, "fecha");
                if (actividades.length > 0) {
                    return actividades;
                } else {
                    return null;
                }
            } catch (PersistentException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * Busca la lista total de actividades en el sistema.
     *
     * @return la lista de actividades, si es que encuentra, si no retornara un null.
     */
    public static Actividad[] buscarActividades() {
        try {
            Actividad[] actividades = ActividadDAO.listActividadByQuery(null, "fecha");
            if (actividades.length > 0) {
                return actividades;
            } else {
                return null;
            }
        } catch (PersistentException e) {
            e.printStackTrace();
        }
        return null;
    }

    //Anotacion

    /**
     * Busca una anotacion especifica en el sistema
     *
     * @param estudiante  Estudiante al que pertenece la anotacion
     * @param profesor    Profesor que la ingreso
     * @param descripcion Descripcion de la anotacion
     * @param positiva    si la anotacion fue positiva o no.
     * @return la anotacion buscada, si es que encuentra, si no retornara un null.
     */
    public static Anotacion buscarAnotacion(Estudiante estudiante, Profesor profesor, String descripcion, boolean positiva) {
        if (estudiante != null && profesor != null && descripcion != null) {
            String query =
                    "estudiante_id_fk=" + estudiante.getId_pk() +
                            " AND profesor_id_fk=" + profesor.getId_pk() +
                            " AND descripcion ='" + descripcion +
                            "' AND positiva = " + positiva;
            try {
                Anotacion[] anotaciones = AnotacionDAO.listAnotacionByQuery(query, null);
                if (anotaciones.length > 0) {
                    return anotaciones[0];
                } else {
                    return null;
                }
            } catch (PersistentException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * Busca una lista de anotaciones de un estudiante
     *
     * @param estudiante Estudiante al que pertenecen las anotaciones
     * @return la lista de anotaciones, si es que encuentra, si no retornara un null.
     */
    public static Anotacion[] buscarAnotaciones(Estudiante estudiante) {
        if (estudiante != null) {
            String query = "estudiante_id_fk=" + estudiante.getId_pk();
            try {
                Anotacion[] anotaciones = AnotacionDAO.listAnotacionByQuery(query, null);
                if (anotaciones.length > 0) {
                    return anotaciones;
                } else {
                    return null;
                }
            } catch (PersistentException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * Busca una lista de anotaciones ingresadas por un profesor
     *
     * @param profesor Profesor que ingreso las anotaciones
     * @return la lista de anotaciones, si es que encuentra, si no retornara un null.
     */
    public static Anotacion[] buscarAnotaciones(Profesor profesor) {
        if (profesor != null) {
            try {
                String query = "profesor_id_fk = " + profesor.getId_pk();
                Anotacion[] anotaciones = AnotacionDAO.listAnotacionByQuery(query, null);
                if (anotaciones.length > 0) {
                    return anotaciones;
                } else {
                    return null;
                }
            } catch (PersistentException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * Busca la lista de anotaciones total del sistema.
     *
     * @return la lista de anotaciones, si es que encuentra, si no retornara un null.
     */
    public static Anotacion[] buscarAnotaciones() {
        try {
            Anotacion[] anotaciones = AnotacionDAO.listAnotacionByQuery(null, null);
            if (anotaciones.length > 0) {
                return anotaciones;
            } else {
                return null;
            }
        } catch (PersistentException e) {
            e.printStackTrace();
        }
        return null;
    }

    //Apoderado

    /**
     * Busca un apoderado en especifico en el sistema, solo necesita su rut ya que estos debieran ser unicos.
     *
     * @param rut Rut del apoderado
     * @return El apoderado buscado, si lo encuentra, si no retorna un null.
     */
    public static Apoderado buscarApoderado(String rut) {
        if (rut != null) {
            String query = "rut = '" + rut + "'";
            try {
                return ApoderadoDAO.loadApoderadoByQuery(query, null);
            } catch (PersistentException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * Busca la lista de apoderados de un colegio
     *
     * @param colegio Colegio al que pertenecen los apoderados
     * @return la lista de apoderados, si es que encuentra, si no retornara un null.
     */
    public static Apoderado[] buscarApoderados(Colegio colegio) {
        if (colegio != null) {
            String query = "colegio_id_fk = " + colegio.getId_pk();
            try {
                Apoderado[] apoderados = ApoderadoDAO.listApoderadoByQuery(query, "nombre");
                if (apoderados.length > 0) {
                    return apoderados;
                } else {
                    return null;
                }
            } catch (PersistentException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * Busca la lista de apoderados total del sistema
     *
     * @return la lista de apoderados, si es que encuentra, si no retornara un null.
     */
    public static Apoderado[] buscarApoderados() {
        try {
            Apoderado[] apoderados = ApoderadoDAO.listApoderadoByQuery(null, "nombre");
            if (apoderados.length > 0) {
                return apoderados;
            } else {
                return null;
            }
        } catch (PersistentException e) {
            e.printStackTrace();
        }
        return null;
    }


    //Asignatura

    /**
     * Busca una asignatura especifica en el sistema.
     *
     * @param nombre Nombre de la asignatura
     * @param curso  Curso al que pertenece
     * @return retorna la asignatura buscada, si la encuentra, si no retorna un null.
     */
    public static Asignatura buscarAsignatura(String nombre, Curso curso) {
        if (nombre != null && curso != null) {
            try {
                Asignatura[] asignaturas = AsignaturaDAO.listAsignaturaByQuery("nombre = '" + nombre + "' AND curso_id_fk='" + curso.getId_pk() + "'", null);
                if (asignaturas.length > 0) {
                    return asignaturas[0];
                } else {
                    return null;
                }
            } catch (PersistentException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * Busca la lista de asignaturas de un curso.
     *
     * @param curso Curso al que pertence la asignatura
     * @return la lista de asignaturas, si es que encuentra, si no retorna un null
     */
    public static Asignatura[] buscarAsignaturas(Curso curso) {
        if (curso != null) {
            try {
                Asignatura[] asignaturas = AsignaturaDAO.listAsignaturaByQuery("curso_id_fk='" + curso.getId_pk() + "'", "nombre");
                if (asignaturas.length > 0) {
                    return asignaturas;
                } else {
                    return null;
                }
            } catch (PersistentException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * Busca la lista de asignaturas que imparte un profesor
     *
     * @param profesor Profesor que imparte las asignaturas
     * @return la lista de asignaturas, si es que encuentra, si no retorna un null
     */
    public static Asignatura[] buscarAsignaturas(Profesor profesor) {
        if (profesor != null) {
            try {
                String query = "profesor_id_fk = " + profesor.getId_pk();
                Asignatura[] asignaturas = AsignaturaDAO.listAsignaturaByQuery(query, "nombre");
                if (asignaturas.length > 0) {
                    return asignaturas;
                } else {
                    return null;
                }
            } catch (PersistentException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * Busca todas las asignaturas del sistema.
     *
     * @return la lista de asignaturas, si es que encuentra, si no retorna un null
     */
    public static Asignatura[] buscarAsignaturas() {
        try {
            Asignatura[] asignaturas = AsignaturaDAO.listAsignaturaByQuery(null, "nombre");
            if (asignaturas.length > 0) {
                return asignaturas;
            } else {
                return null;
            }
        } catch (PersistentException e) {
            e.printStackTrace();
        }
        return null;
    }

    //Asistencia

    /**
     * Busca una asistencia especifica en el sistema.
     *
     * @param estudiante Estudiante al que pertenece
     * @param dia        Dia en que ocurrio
     * @param asistio    si asistio o no
     * @return La asistencia especifica buscada, si la encuentra, si no retorna null.
     */
    public static Asistencia buscarAsistencia(Estudiante estudiante, Date dia, boolean asistio) {
        if (estudiante != null && dia != null) {
            try {
                String query =
                        "estudiante_id_fk =" + estudiante.getId_pk() +
                                "AND dia ='" + format.format(dia) +
                                "'AND asistio =" + asistio;
                Asistencia[] asistencias = AsistenciaDAO.listAsistenciaByQuery(query, null);
                if (asistencias.length > 0) {
                    return asistencias[0];
                } else {
                    return null;
                }
            } catch (PersistentException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * Busca la lista de asistencias de un estudiante.
     *
     * @param estudiante Estudiante al que pertenecen las asistencias
     * @return la lista de asistencias si las encuentra, si no retorna un null
     */
    public static Asistencia[] buscarAsistencias(Estudiante estudiante) {
        if (estudiante != null) {
            try {
                String query = "estudiante_id_fk =" + estudiante.getId_pk();
                Asistencia[] asistencias = AsistenciaDAO.listAsistenciaByQuery(query, "dia");
                if (asistencias.length > 0) {
                    return asistencias;
                } else {
                    return null;
                }
            } catch (PersistentException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * Busca la lista de asistencias que existen en el sistema.
     *
     * @return la lista de asistencias si las encuentra, si no retorna un null
     */
    public static Asistencia[] buscarAsistencias() {
        try {
            Asistencia[] asistencias = AsistenciaDAO.listAsistenciaByQuery(null, "dia");
            if (asistencias.length > 0) {
                return asistencias;
            } else {
                return null;
            }
        } catch (PersistentException e) {
            e.printStackTrace();
        }
        return null;
    }

    //Colegio

    /**
     * Busca un colegio especifico.
     *
     * @param nombre Nombre del colegio buscado (Tal vez se deba cambiar por un id)
     * @return El colegio buscado si se encuentra, si no retorna null.
     */
    public static Colegio buscarColegio(String nombre) {
        if (nombre != null) {
            try {
                Colegio[] colegios = ColegioDAO.listColegioByQuery("nombre = '" + nombre + "'", null);
                if (colegios.length > 0) {
                    return colegios[0];
                } else {
                    return null;
                }
            } catch (PersistentException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * Busca todos los colegios en el sistema
     *
     * @return La lista de colegios si encuentra, si no retorna un null
     */
    public static Colegio[] buscarColegios() {
        try {
            Colegio[] colegios = ColegioDAO.listColegioByQuery(null, null);
            if (colegios.length > 0) {
                return colegios;
            } else {
                return null;
            }
        } catch (PersistentException e) {
            e.printStackTrace();
        }
        return null;
    }

    //Curso

    /**
     * Busca un curso especifico en el sistema
     *
     * @param nivel Nivel del curso
     * @param letra Letra del curso
     * @return El curso buscado si lo encuentra, si no retorna null
     */
    public static Curso buscarCurso(int nivel, String letra) {
        if (letra != null) {
            try {
                Curso[] cursos = CursoDAO.listCursoByQuery("nivel='" + nivel + "' AND letra='" + letra + "'", null);
                if (cursos.length > 0) {
                    return cursos[0];
                } else {
                    return null;
                }
            } catch (PersistentException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * Busca la lista de cursos en un colegio.
     *
     * @param colegio Colegio en el que se buscara
     * @return la lista de cursos si es que encuentra, si no retorna un null
     */
    public static Curso[] buscarCursos(Colegio colegio) {
        if (colegio != null) {
            try {
                Curso[] cursos = CursoDAO.listCursoByQuery("colegio_id_fk =" + colegio.getId_pk(), "nivel, letra");
                if (cursos.length > 0) {
                    return cursos;
                } else {
                    return null;
                }
            } catch (PersistentException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * Busca todos los cursos existentes en el sistema
     *
     * @return la lista de cursos si es que encuentra, si no retorna un null
     */
    public static Curso[] buscarCursos() {
        try {
            Curso[] cursos = CursoDAO.listCursoByQuery(null, "nivel, letra");
            if (cursos.length > 0) {
                return cursos;
            } else {
                return null;
            }
        } catch (PersistentException e) {
            e.printStackTrace();
        }
        return null;
    }

    //Estudiante

    /**
     * Busca un estudiante especifico segun su rut, ya que este debe ser unico
     *
     * @param rut Rut del estudiante a buscar
     * @return el estudiante buscado si lo encuentra, si no retorna un null
     */
    public static Estudiante buscarEstudiante(String rut) {
        if (rut != null) {
            try {
                String query = "rut = '" + rut + "'";
                Estudiante[] estudiantes = EstudianteDAO.listEstudianteByQuery(query, null);
                if (estudiantes.length > 0) {
                    return estudiantes[0];
                } else {
                    return null;
                }
            } catch (PersistentException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * Busca la lista de estudiantes de un curso.
     *
     * @param curso Curso en el que se buscara
     * @return La lista de estudiantes si es que encuentra, si no retornara un null
     */
    public static Estudiante[] buscarEstudiantes(Curso curso) {
        if (curso != null) {
            try {
                Estudiante[] estudiantes = EstudianteDAO.listEstudianteByQuery("curso_id_fk='" + curso.getId_pk() + "'", "nombre");
                if (estudiantes.length > 0) {
                    return estudiantes;
                } else {
                    return null;
                }
            } catch (PersistentException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * Busca la lista de estudiantes de un apoderado
     *
     * @param apoderado apoderado al que pertenecen los estudiantes a buscar
     * @return La lista de estudiante si es que encuentra, si no retornara null.
     */
    public static Estudiante[] buscarEstudiantes(Apoderado apoderado) {
        if (apoderado != null) {
            try {
                String query = "apoderado_id_fk =" + apoderado.getId_pk();
                Estudiante[] estudiantes = EstudianteDAO.listEstudianteByQuery(query, "nombre");
                if (estudiantes.length > 0) {
                    return estudiantes;
                } else {
                    return null;
                }
            } catch (PersistentException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * Busca todos los estudiantes del sistema.
     *
     * @return La lista de estudiantes, si es que encuentra
     */
    public static Estudiante[] buscarEstudiantes() {
        try {
            Estudiante[] estudiantes = EstudianteDAO.listEstudianteByQuery(null, "nombre");
            if (estudiantes.length > 0) {
                return estudiantes;
            } else {
                return null;
            }
        } catch (PersistentException e) {
            e.printStackTrace();
        }
        return null;

    }

    //Nota

    /**
     * Busca una nota especifica en el sistema
     *
     * @param estudiante Estudiante al que pertenece la nota
     * @param asignatura Asignatura a la que pertene la nota
     * @param valor      Valor de la nota
     * @return La nota buscada, si es que la encuentra, si no retornara null.
     */
    public static Nota buscarNota(Estudiante estudiante, Asignatura asignatura, double valor) {
        if (estudiante != null && asignatura != null) {
            try {
                String query = "estudiante_id_fk=" + estudiante.getId_pk() +
                        "AND asignatura_id_fk = " + asignatura.getId_pk();
                Nota[] notas = NotaDAO.listNotaByQuery(query, null);
                if (notas.length > 0) {
                    for (Nota nota : notas) {
                        DecimalFormat format = new DecimalFormat("#.#");
                        format.setRoundingMode(RoundingMode.CEILING);
                        if (format.format(nota.getValor()).equals(format.format(valor))) {
                            return nota;
                        }
                    }
                } else {
                    return null;
                }
            } catch (PersistentException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * Busca la lista de notas de un estudiante
     *
     * @param estudiante Estudiante al que pertenecen las notas
     * @return La lista de notas si encuentra, si no retornara null.
     */
    public static Nota[] buscarNotas(Estudiante estudiante) {
        if (estudiante != null) {
            try {
                String query = "estudiante_id_fk=" + estudiante.getId_pk();
                Nota[] notas = NotaDAO.listNotaByQuery(query, null);
                if (notas.length > 0) {
                    return notas;
                } else {
                    return null;
                }
            } catch (PersistentException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * Busca la lista de notas en una asignatura.
     *
     * @param asignatura Asignatura a la que pertenecen las notas
     * @return la lista de notas si es que encuentra, si no retornara un null
     */
    public static Nota[] buscarNotas(Asignatura asignatura) {
        if (asignatura != null) {
            try {
                String query = "asignatura_id_fk = " + asignatura.getId_pk();
                Nota[] notas = NotaDAO.listNotaByQuery(query, null);
                if (notas.length > 0) {
                    return notas;
                } else {
                    return null;
                }
            } catch (PersistentException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * Busca las notas presentes en el sistema.
     *
     * @return La lista de notas si es que encuentra, si no retorna null.
     */
    public static Nota[] buscarNotas() {
        try {
            Nota[] notas = NotaDAO.listNotaByQuery(null, null);
            if (notas.length > 0) {
                return notas;
            } else {
                return null;
            }
        } catch (PersistentException e) {
            e.printStackTrace();
        }
        return null;
    }

    //Profesor

    /**
     * Busca un profesor especifico segun su rut, ya que este debe ser unico
     *
     * @param rut Rut del profesor a buscar
     * @return El profesor buscado si lo encuentra, si no retornara un null
     */
    public static Profesor buscarProfesor(String rut) {
        if (rut != null) {
            try {
                Profesor[] profesores = ProfesorDAO.listProfesorByQuery("rut = '" + rut + "'", null);
                if (profesores.length > 0) {
                    return profesores[0];
                } else {
                    return null;
                }
            } catch (PersistentException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * Busca la lista de profesores que hacen clases a un curso
     *
     * @param curso Curso al cual hacen clases los profesores
     * @return La lista de profesores si es que encuentra, si no retornara un null
     */
    public static Profesor[] buscarProfesores(Curso curso) {
        if (curso != null) {
            Asignatura[] asignaturas = Search.buscarAsignaturas(curso);
            if (asignaturas != null) {
                Profesor[] profesores = new Profesor[asignaturas.length];
                for (int x = 0; x < asignaturas.length; x++) {
                    profesores[x] = asignaturas[x].getProfesor_id_fk();
                }
                if (profesores.length > 0) {
                    return profesores;
                } else {
                    return null;
                }
            }
        }
        return null;
    }

    /**
     * Busca la lista de profesores en un colegio
     *
     * @param colegio Colegio en el que se buscaran los profesores
     * @return La lista de profesores si es que encuentra, si no retornara un null
     */
    public static Profesor[] buscarProfesores(Colegio colegio) {
        if (colegio != null) {
            String query = "colegio_id_fk = " + colegio.getId_pk() + "";
            try {
                Profesor[] profesores = ProfesorDAO.listProfesorByQuery(query, "nombre");
                if (profesores.length > 0) {
                    return profesores;
                } else {
                    return null;
                }
            } catch (PersistentException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    public static Profesor[] buscarProfesores() {
        try {
            Profesor[] profesores = ProfesorDAO.listProfesorByQuery(null, "nombre");
            if (profesores.length > 0) {
                return profesores;
            } else {
                return null;
            }
        } catch (PersistentException e) {
            e.printStackTrace();
        }
        return null;
    }


}
