/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package so.aulavirtual.mysqlDAO;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import so.aulavirtual.dao.UsuarioDAO;
import so.aulavirtual.utilities.GeneralVariables;
import so.aulavirtual.utilities.ResponseHelper;

/**
 *
 * @author sistem17user
 */
public class UsuarioMysqlDAO implements UsuarioDAO {

	@Override
	public JSONObject listarUsuarios(JSONObject datos) throws Exception {
		JSONObject jreturn = new JSONObject();
		JSONArray lista = new JSONArray();
		JSONObject data = new JSONObject();
		Connection con = null;
		PreparedStatement pst = null;
		ResultSet rSet = null;
		int cantidadRegistros = 0;
		String sql;
		String condicion = "";
		try {
			if (datos.has("dniUsuario")) {
				condicion = " where mu.idnumber = " + datos.getInt("dniUsuario") + " ";
			}
			con = MysqlDAOFactory.obtenerConexion(GeneralVariables.nameDB);
			sql = " SELECT "
				+ "	mu.id, "
				+ "	IFNULL(mu.firstname, ''), "
				+ "	IFNULL(mu.lastname, ''), "
				+ "	IFNULL(mu.apePat, ''), "
				+ "	IFNULL(mu.apeMat, ''), "
				+ "	IFNULL(mu.auth, ''), "
				+ "	IFNULL(mu.username, ''), "
				+ "	IFNULL(mu.idnumber, ''), "
				+ "	IFNULL(uid.`data`, ''), "
				+ "	IFNULL(mu.desSede, ''), "
				+ "	IFNULL(mu.desNiv, ''), "
				+ "	IFNULL(mu.desGra, ''), "
				+ "	IFNULL(mu.conTemp, '') "
				+ " FROM "
				+ "	mdl_user mu "
				+ " LEFT JOIN mdl_user_info_data uid  "
				+ " ON uid.userid = mu.id "
				+ " " + condicion + " "
				+ " ORDER BY mu.id DESC "
				+ " LIMIT " + datos.getInt("start") + ", " + datos.getInt("length");
			System.out.println("QUERY ---> " + sql);
			pst = con.prepareStatement(sql);
			rSet = pst.executeQuery();
			int conta = datos.getInt("start") + 1;
			while (rSet.next()) {
				JSONObject obj = new JSONObject();
				int c = 1;
				obj.put("numeral", conta);
				obj.put("codigoUsuario", rSet.getInt(c++));
				obj.put("nombreUsuario", rSet.getString(c++));
				obj.put("apellidosUsuario", rSet.getString(c++));
				obj.put("apepatUsuario", rSet.getString(c++));
				obj.put("apematUsuario", rSet.getString(c++));
				obj.put("tipoUsuario", rSet.getString(c++));
				obj.put("correoUsuario", rSet.getString(c++));
				obj.put("dniUsuario", rSet.getString(c++));
				obj.put("rolUsuario", rSet.getString(c++));
				obj.put("sedeUsuario", rSet.getString(c++));
				obj.put("nivelUsuario", rSet.getString(c++));
				obj.put("gradoUsuario", rSet.getString(c++));
				obj.put("claveUsuario", rSet.getString(c++));
				lista.put(obj);
				conta++;
			}
			sql = " select count(*) "
				+ " from mdl_user mu  "
				+ " left join mdl_user_info_data uid "
				+ " on uid.userid = mu.id "
				+ " " + condicion + " ";
			pst = con.prepareStatement(sql);
			rSet = pst.executeQuery();
			rSet.next();
			cantidadRegistros = rSet.getInt(1);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (rSet != null) {
					rSet.close();
				}
				if (pst != null) {
					pst.close();
				}
				if (con != null) {
					con.close();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		jreturn.put("data", lista);
		jreturn.put("recordsFiltered", cantidadRegistros);
		jreturn.put("recordsTotal", cantidadRegistros);
		jreturn.put("draw", datos.getInt("draw"));
		return jreturn;
	}

	@Override
	public JSONObject listarSede(JSONObject datos) throws Exception {
		JSONObject jreturn;
		JSONArray lista = new JSONArray();
		Connection con = null;
		PreparedStatement pst = null;
		ResultSet rSet = null;
		String sql;
		ResponseHelper response = new ResponseHelper();
		try {
			con = MysqlDAOFactory.obtenerConexion(GeneralVariables.nameDB);
			sql = " SELECT "
				+ "	u.cod_usu, "
				+ "	u.sede "
				+ "FROM "
				+ "	usuario AS u "
				+ "WHERE "
				+ "	est_usu = 1 ";
			pst = con.prepareStatement(sql);
			rSet = pst.executeQuery();
			while (rSet.next()) {
				JSONObject obj = new JSONObject();
				obj.put("codigoSede", rSet.getInt(1));
				obj.put("nombreSede", rSet.getString(2));
				lista.put(obj);
			}
			if (lista.length() >= 1) {
				response.setStatus(true);
				response.setResults(lista);
			} else {
				response.setStatus(false);
			}
		} catch (Exception e) {
			e.printStackTrace();
			response.setStatus(false);
			response.setMessage("Error --->" + e.getMessage());
		} finally {
			try {
				if (rSet != null) {
					rSet.close();
				}
				if (pst != null) {
					pst.close();
				}
				if (con != null) {
					con.close();
				}
			} catch (Exception e) {
				e.printStackTrace();
				response.setStatus(false);
				response.setMessage("Error --->" + e.getMessage());
			}
		}
		jreturn = new JSONObject(response);
		return jreturn;
	}

	@Override
	public JSONObject listarNivel(JSONObject datos) throws Exception {
		JSONObject jreturn;
		JSONArray lista = new JSONArray();
		Connection con = null;
		PreparedStatement pst = null;
		ResultSet rSet = null;
		String sql;
		ResponseHelper response = new ResponseHelper();
		try {
			con = MysqlDAOFactory.obtenerConexion(GeneralVariables.nameDB);
			sql = " SELECT "
				+ "	mdc.id, "
				+ "	mdc.`name` "
				+ " FROM "
				+ "	mdl_course_categories AS mdc "
				+ " WHERE "
				+ "	mdc.parent = 0 "
				+ "AND mdc.id NOT IN (2, 4) ";
			pst = con.prepareStatement(sql);
			rSet = pst.executeQuery();
			while (rSet.next()) {
				JSONObject obj = new JSONObject();
				obj.put("codigoNivel", rSet.getInt(1));
				obj.put("nombreNivel", rSet.getString(2));
				lista.put(obj);
			}
			if (lista.length() >= 1) {
				response.setStatus(true);
				response.setResults(lista);
			} else {
				response.setStatus(false);
			}
		} catch (Exception e) {
			e.printStackTrace();
			response.setStatus(false);
			response.setMessage("Error --->" + e.getMessage());
		} finally {
			try {
				if (rSet != null) {
					rSet.close();
				}
				if (pst != null) {
					pst.close();
				}
				if (con != null) {
					con.close();
				}
			} catch (Exception e) {
				e.printStackTrace();
				response.setStatus(false);
				response.setMessage("Error --->" + e.getMessage());
			}
		}
		jreturn = new JSONObject(response);
		return jreturn;
	}

	@Override
	public JSONObject listarGrado(JSONObject datos) throws Exception {
		JSONObject jreturn;
		JSONArray lista = new JSONArray();
		Connection con = null;
		PreparedStatement pst = null;
		ResultSet rSet = null;
		String sql;
		ResponseHelper response = new ResponseHelper();
		try {
			con = MysqlDAOFactory.obtenerConexion(GeneralVariables.nameDB);
			sql = " SELECT "
				+ "	mdc.id, "
				+ "	mdc. NAME "
				+ " FROM "
				+ "	mdl_course_categories AS mdc "
				+ " WHERE "
				+ "	mdc.parent = ? ";
			pst = con.prepareStatement(sql);
			pst.setInt(1, datos.getInt("parent"));
			rSet = pst.executeQuery();
			while (rSet.next()) {
				JSONObject obj = new JSONObject();
				obj.put("codigoGrado", rSet.getInt(1));
				obj.put("nombreGrado", rSet.getString(2));
				lista.put(obj);
			}
			if (lista.length() >= 1) {
				response.setStatus(true);
				response.setResults(lista);
			} else {
				response.setStatus(false);
			}
		} catch (Exception e) {
			e.printStackTrace();
			response.setStatus(false);
			response.setMessage("Error --->" + e.getMessage());
		} finally {
			try {
				if (rSet != null) {
					rSet.close();
				}
				if (pst != null) {
					pst.close();
				}
				if (con != null) {
					con.close();
				}
			} catch (Exception e) {
				e.printStackTrace();
				response.setStatus(false);
				response.setMessage("Error --->" + e.getMessage());
			}
		}
		jreturn = new JSONObject(response);
		return jreturn;
	}

	@Override
	public JSONObject eliminarUsuario(JSONObject datos) throws Exception {
		JSONObject jreturn;
		Connection con = null;
		PreparedStatement pst = null;
		ResultSet rSet = null;
		int rs = 0;
		String sql;
		ResponseHelper response = new ResponseHelper();
		try {
			con = MysqlDAOFactory.obtenerConexion(GeneralVariables.nameDB);
			con.setAutoCommit(false);
			sql = " delete from mdl_user_enrolments "
				+ " where userid = ? ";
			pst = con.prepareStatement(sql);
			pst.setInt(1, datos.getInt("codigoUsuario"));
			rs = pst.executeUpdate();
			if (rs >= 0) {
				sql = " delete from mdl_user_info_data "
					+ " where userid = ? ";
				pst = con.prepareStatement(sql);
				pst.setInt(1, datos.getInt("codigoUsuario"));
				rs = pst.executeUpdate();
				if (rs >= 0) {
					sql = " delete from mdl_user "
						+ " where id = ? ";
					pst = con.prepareStatement(sql);
					pst.setInt(1, datos.getInt("codigoUsuario"));
					rs = pst.executeUpdate();
					if (rs >= 0) {
						con.commit();
						response.setStatus(true);
						response.setMessage("Usuario eliminado correctamente");
					} else {
						response.setStatus(false);
						response.setMessage("Ocurrio un error al eliminar Usuario");
					}
				} else {
					response.setStatus(false);
					response.setMessage("Ocurrio un error al eliminar Usuario");
				}
			} else {
				response.setStatus(false);
				response.setMessage("Ocurrio un error al eliminar Usuario");
			}
		} catch (Exception e) {
			e.printStackTrace();
			response.setStatus(false);
			response.setMessage("Error --->" + e.getMessage());
		} finally {
			try {
				if (rSet != null) {
					rSet.close();
				}
				if (pst != null) {
					pst.close();
				}
				if (con != null) {
					con.close();
				}
			} catch (Exception e) {
				e.printStackTrace();
				response.setStatus(false);
				response.setMessage("Error --->" + e.getMessage());
			}
		}
		jreturn = new JSONObject(response);
		return jreturn;
	}

	@Override
	public JSONObject nuevoUsuario(JSONObject datos) throws Exception {
		JSONObject jreturn;
		Connection con = null;
		PreparedStatement pst = null;
		ResultSet rSet = null;
		int rs = 0;
		String sql;
		ResponseHelper response = new ResponseHelper();
		try {
			String param;
			String data;
			int tipoUsuario;
			switch (datos.getString("rolUsuario")) {
				case "DOCENTE":
					param = "";
					data = "";
					tipoUsuario = 0;
					break;
				case "ESTUDIANTE":
					param = " desNiv,  desGra,  desSede, ";
					data = " UPPER(?), UPPER(?), UPPER(?),	 ";
					tipoUsuario = 1;
					break;
				default:
					param = " desSede, ";
					data = " ?, ";
					tipoUsuario = 2;
			}
			con = MysqlDAOFactory.obtenerConexion(GeneralVariables.nameDB);
			con.setAutoCommit(false);
			sql = " insert into mdl_user "
				+ "  ( "
				+ "  auth, "
				+ "  confirmed, "
				+ "  mnethostid, "
				+ "  username, "
				+ "  password, "
				+ "  idnumber, "
				+ "  firstname, "
				+ "  lastname, "
				+ "  email, "
				+ "  city, "
				+ "  country, "
				+ "  lang, "
				+ "  calendartype, "
				+ "  timezone, "
				+ "  apePat, "
				+ "  apeMat, "
				+ param
				+ "  conTemp"
				+ "  )"
				+ "  values ( LOWER(?), ?, ?, ?, ?, ?, UPPER(?), UPPER(?), ?, ?,"
				+ "  ?, ?, ?, ?, UPPER(?), UPPER(?), " + data + " ? ) ";
			pst = con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
			int c = 1;
			pst.setString(c++, datos.getString("tipoUsuario"));
			pst.setInt(c++, 1);
			pst.setInt(c++, 1);
			pst.setString(c++, datos.getString("correoUsuario"));
			pst.setString(c++, "not cached");
			pst.setString(c++, datos.getString("dniUsuario"));
			pst.setString(c++, datos.getString("nombreUsuario"));
			pst.setString(c++, datos.getString("apepatUsuario") + " " + datos.getString("apematUsuario"));
			pst.setString(c++, datos.getString("correoUsuario"));
			pst.setString(c++, "Lima");
			pst.setString(c++, "PE");
			pst.setString(c++, "en");
			pst.setString(c++, "gregorian");
			pst.setString(c++, "America/Lima");
			pst.setString(c++, datos.getString("apepatUsuario"));
			pst.setString(c++, datos.getString("apematUsuario"));
			if (tipoUsuario == 1) {
				pst.setString(c++, datos.getString("nivelUsuario"));
				pst.setString(c++, datos.getString("gradoUsuario"));
				pst.setString(c++, datos.getString("sedeUsuario"));
			} else if (tipoUsuario == 2) {
				pst.setString(c++, datos.getString("sedeUsuario"));
			}
			pst.setString(c++, datos.getString("claveUsuario"));
			rs = pst.executeUpdate();
			if (rs == 1) {
				rSet = pst.getGeneratedKeys();
				rSet.next();
				int codigoUsuario = rSet.getInt(1);
				sql = " insert into mdl_user_info_data(userid, fieldid, data) "
					+ " values ( ?, 4, ? ) ";
				pst = con.prepareStatement(sql);
				pst.setInt(1, codigoUsuario);
				pst.setString(2, datos.getString("rolUsuario"));
				rs = pst.executeUpdate();
				if (rs == 1) {
					if (datos.getString("rolUsuario").equals("ESTUDIANTE")) {
						sql = " insert into mdl_user_enrolments (enrolid, userid, timeend) "
							+ " select me.id, ?, 0 from mdl_course as mc "
							+ " inner join mdl_enrol as me "
							+ " on me.courseid = mc.id "
							+ " where me.enrol = 'manual' "
							+ " and category = ? ";
						pst = con.prepareStatement(sql);
						pst.setInt(1, codigoUsuario);
						pst.setInt(2, datos.getInt("codigoGrado"));
						rs = pst.executeUpdate();
						if (rs >= 1) {
							con.commit();
							response.setStatus(true);
							response.setMessage("Usuario correctamente registrado");
						} else {
							response.setStatus(false);
							response.setMessage("Ocurrió un error al registrar cursos");
						}
					} else {
						con.commit();
						response.setStatus(true);
						response.setMessage("Usuario correctamente registrado");
					}
				} else {
					response.setStatus(false);
					response.setMessage("Ocurrió un error al registrar rol");
				}
			} else {
				response.setStatus(false);
				response.setMessage("Ocurrió un error al registrar usuario");
			}
		} catch (Exception e) {
			e.printStackTrace();
			response.setStatus(false);
			response.setMessage("Error --->" + e.getMessage());
		} finally {
			try {
				if (rSet != null) {
					rSet.close();
				}
				if (pst != null) {
					pst.close();
				}
				if (con != null) {
					con.close();
				}
			} catch (Exception e) {
				e.printStackTrace();
				response.setStatus(false);
				response.setMessage("Error --->" + e.getMessage());
			}
		}
		jreturn = new JSONObject(response);
		return jreturn;
	}

	@Override
	public JSONObject editarUsuarios(JSONObject datos) throws Exception {
		JSONObject jreturn;
		Connection con = null;
		PreparedStatement pst = null;
		ResultSet rSet = null;
		int rs;
		String sql;
		ResponseHelper response = new ResponseHelper();
		try {
			con = MysqlDAOFactory.obtenerConexion(GeneralVariables.nameDB);
			con.setAutoCommit(false);
			sql = " update mdl_user  "
				+ " set  "
				+ " auth = ?, "
				+ " username = ?, "
				+ " idnumber = ?, "
				+ " firstname = ?, "
				+ " lastname = ?, "
				+ " email = ?, "
				+ " apePat = ?, "
				+ " apeMat = ?, "
				+ " desNiv = ?, "
				+ " desGra = ?, "
				+ " desSede = ?,  "
				+ " conTemp = ? "
				+ " where id = ? ";
			pst = con.prepareStatement(sql);
			int c = 1;
			pst.setString(c++, datos.getString("tipoUsuario"));
			pst.setString(c++, datos.getString("correoUsuario"));
			pst.setString(c++, datos.getString("dniUsuario"));
			pst.setString(c++, datos.getString("nombreUsuario"));
			pst.setString(c++, datos.getString("apepatUsuario") + " " + datos.getString("apematUsuario"));
			pst.setString(c++, datos.getString("correoUsuario"));
			pst.setString(c++, datos.getString("apepatUsuario"));
			pst.setString(c++, datos.getString("apematUsuario"));
			pst.setString(c++, datos.getString("nivelUsuario"));
			pst.setString(c++, datos.getString("gradoUsuario"));
			pst.setString(c++, datos.getString("sedeUsuario"));
			pst.setString(c++, datos.getString("claveUsuario"));
			pst.setInt(c++, datos.getInt("codigoUsuario"));
			rs = pst.executeUpdate();
			if (rs == 1) {
				sql = " update mdl_user_info_data "
					+ " set data = ? "
					+ " where userid = ? ";
				pst = con.prepareStatement(sql);
				pst.setString(1, datos.getString("rolUsuario"));
				pst.setInt(2, datos.getInt("codigoUsuario"));
				rs = pst.executeUpdate();
				if (rs == 1) {
					con.commit();
					response.setStatus(true);
					response.setMessage("Usuario correctamente modificado");
				} else {
					response.setStatus(false);
					response.setMessage("Error al modificar Rol");
				}
			} else {
				response.setStatus(false);
				response.setMessage("Error al modificar Usuario");
			}
		} catch (SQLException | JSONException e) {
			e.printStackTrace();
			response.setStatus(false);
			response.setMessage("Error --->" + e.getMessage());
		} finally {
			try {
				if (rSet != null) {
					rSet.close();
				}
				if (pst != null) {
					pst.close();
				}
				if (con != null) {
					con.close();
				}
			} catch (SQLException e) {
				e.printStackTrace();
				response.setStatus(false);
				response.setMessage("Error --->" + e.getMessage());
			}
		}
		jreturn = new JSONObject(response);
		return jreturn;
	}

	@Override
	public JSONObject validarUsuario(JSONObject datos) throws Exception {
		JSONObject jreturn;
		Connection con = null;
		PreparedStatement pst = null;
		ResultSet rSet = null;
		String sql;
		ResponseHelper response = new ResponseHelper();
		try {
			con = MysqlDAOFactory.obtenerConexion(GeneralVariables.nameDB);
			String edit = datos.has("codigoUsuario") ? " and username != ?  " : " ";
			sql = " select count(*) from mdl_user "
				+ " where username = ? "
				+ edit;
			pst = con.prepareStatement(sql);
			pst.setString(1, datos.getString("correoUsuario"));
			if (datos.has("codigoUsuario")) {
				pst.setString(2, datos.getString("correoUsuario"));
			}
			rSet = pst.executeQuery();
			rSet.next();
			int cant = rSet.getInt(1);
			if (cant != 0) {
				response.setStatus(false);
				response.setMessage("Este usuario ya existe");
			} else {
				response.setStatus(true);
				response.setMessage("Correcto");
			}
		} catch (Exception e) {
			e.printStackTrace();
			response.setStatus(false);
			response.setMessage("Error --->" + e.getMessage());
		} finally {
			try {
				if (rSet != null) {
					rSet.close();
				}
				if (pst != null) {
					pst.close();
				}
				if (con != null) {
					con.close();
				}
			} catch (Exception e) {
				e.printStackTrace();
				response.setStatus(false);
				response.setMessage("Error --->" + e.getMessage());
			}
		}
		jreturn = new JSONObject(response);
		return jreturn;
	}

}
