//@formatter:off
package com.ejie.aa21b.dao;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;
import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.ejie.aa21b.model.Aa21b20s01;

@Repository
@Transactional
public class Aa21b22s01DaoImpl implements Aa21b22s01Dao {
	private JdbcTemplate jdbcTemplate;
	private static final Logger logger = LoggerFactory
			.getLogger(Aa21b22s01DaoImpl.class);

	/**
	 * Method use to set the datasource.
	 * 
	 * @param dataSource
	 *            DataSource
	 * @return
	 */
	@Resource
	public void setDataSource(DataSource dataSource) {
		this.jdbcTemplate = new JdbcTemplate(dataSource);
	}

	private int buscarGrupoExpediente(Aa21b20s01 expediente) {
		logger.info("buscamos grupo de expedientes");
		String consulta = "SELECT cgrupo22 FROM AA21B22S01 WHERE NEXPEREL22=? AND rownum=1";
		int respuesta;
		try {
			respuesta = this.jdbcTemplate.queryForInt(consulta,
					expediente.getRefExp());
		} catch (Exception e) {
			respuesta = -1;
		}
		return respuesta;
	}

	private int buscarGrupoExpedienteOrig(String expediente) {
		logger.info("buscamos grupo de expedientes");
		String consulta = "SELECT cgrupo22 FROM AA21B22S01 WHERE NEXPEREL22=? AND rownum=1";
		int respuesta;
		try {
			respuesta = this.jdbcTemplate.queryForInt(consulta, expediente);
		} catch (Exception e) {
			respuesta = -1;
		}
		return respuesta;
	}

	// 20161117 INI - INIGO
	@Override
	public ArrayList<Object> updateAsociados(
			ArrayList<String> listaExpAsociados,
			ArrayList<String> listaExpDesasociados, Aa21b20s01 expediente) {
		logger.info("Entra en updateAsociados, actualiza ls expedientes asociados de un expediente");
		int correlativoGrupo = 0;
		int correlativoGrupoAux = 0;
		String query = "";
		String queryExiste = "";
		String strExpedienteAux = "";
		Aa21b20s01 expedienteAux = null;
		ArrayList<String> listaExpAsociar = new ArrayList<String>();
		ArrayList<String> listaExpNoAsociar = new ArrayList<String>();
		ArrayList<String> listaExpNuevosAsociar = new ArrayList<String>();

		int c = this.buscarGrupoExpediente(expediente);
		if (c > 0) {
			expediente.setGrupo(String.valueOf(c));
		}

		// //Quito al expediente de los grupos donde esté
		// logger.info("Quito al expediente de los grupos donde esté");
		// query = "DELETE FROM AA21B22S01 WHERE NEXPEREL22=?";
		// Aa21b22s01DaoImpl.logger.info("SQL = " + query);
		// Aa21b22s01DaoImpl.logger.info("PARAM1=" + expediente.getRefExp());
		// this.jdbcTemplate.update(query, expediente.getRefExp());

		// Quito de la grupo los expedientes que estén en la lista de
		// listaExpDesasociados y no estén en la lista de listaExpAsociados
		// if (listaExpDesasociados != null && listaExpDesasociados.size() > 0)
		// {
		// for (String s : listaExpAsociar) {
		// if (!listaExpAsociados.contains(s)) {
		// logger.info("Quito al expediente del grupo");
		// query = "DELETE FROM AA21B22S01 WHERE NEXPEREL22=?";
		// Aa21b22s01DaoImpl.logger.info("SQL = " + query);
		// Aa21b22s01DaoImpl.logger.info("PARAM1=" + expediente.getRefExp());
		// this.jdbcTemplate.update(query, expediente.getRefExp());
		// }
		// }
		// }

		if (expediente.getGrupo() != null && !expediente.getGrupo().equals("")) {
			correlativoGrupo = Integer.valueOf(expediente.getGrupo())
					.intValue();
			logger.info("Tiene grupo=" + correlativoGrupo);

			// Si tiene grupo
			logger.info("Miramos cuántos expedientes contiene el grupo...");
			query = "SELECT count(1) FROM AA21B22S01 WHERE CGRUPO22=?";
			Aa21b22s01DaoImpl.logger.info("SQL = " + query);
			Aa21b22s01DaoImpl.logger.info("PARAM1=" + correlativoGrupo);
			int num = this.jdbcTemplate.queryForInt(query, correlativoGrupo);
			logger.info("El grupo contiene: " + num + " expedientes asociados.");

			// Si en el grupo sólo están él mismo y otro expediente encontes
			// borramos el grupo
			if (num == 2) {
				logger.info("El grupo del expediente sólo contiene a sí mismo y a otro expediente -> Borramos el grupo");
				query = "DELETE FROM AA21B22S01 WHERE CGRUPO22=?";
				Aa21b22s01DaoImpl.logger.info("SQL = " + query);
				Aa21b22s01DaoImpl.logger.info("PARAM1=" + correlativoGrupo);
				this.jdbcTemplate.update(query, correlativoGrupo);
			} else {
				// logger.info("Sacamos al expediente del grupo");
				// query = "DELETE FROM AA21B22S01 WHERE NEXPEREL22=?";
				// Aa21b22s01DaoImpl.logger.info("SQL = " + query);
				// Aa21b22s01DaoImpl.logger.info("PARAM1=" +
				// expediente.getRefExp());
				// this.jdbcTemplate.update(query, expediente.getRefExp());
			}
		}

		// Quito al expediente de los grupos donde esté
		logger.info("Quito al expediente de los grupos donde esté");
		query = "DELETE FROM AA21B22S01 WHERE NEXPEREL22=?";
		Aa21b22s01DaoImpl.logger.info("SQL = " + query);
		Aa21b22s01DaoImpl.logger.info("PARAM1=" + expediente.getRefExp());
		this.jdbcTemplate.update(query, expediente.getRefExp());

		correlativoGrupo = Integer.MIN_VALUE;
		// Todos los expedientes a asociar tienen que ser del mismo grupo.
		// Si hay alguno de otro grupo lo dejamos fuera.
		if (listaExpAsociados != null && listaExpAsociados.size() > 0) {
			for (int i = 0; i < listaExpAsociados.size(); i++) {

				strExpedienteAux = listaExpAsociados.get(i);
				expedienteAux = new Aa21b20s01();
				expedienteAux.setRefExp(strExpedienteAux.replaceAll("-", "/"));

				if (expedienteAux != null) {
					correlativoGrupoAux = this
							.buscarGrupoExpediente(expedienteAux);

					if (correlativoGrupoAux <= 0) {
						listaExpAsociar.add(strExpedienteAux);
					} else {
						if (correlativoGrupo == Integer.MIN_VALUE) {
							correlativoGrupo = correlativoGrupoAux;
							logger.info("Grupo a añadirse=" + correlativoGrupo);
						}

						if (correlativoGrupoAux == correlativoGrupo) {
							if (correlativoGrupo != c) {
								listaExpAsociar.add(strExpedienteAux);
							}
						} else {
							if (correlativoGrupo != c) {
								listaExpNoAsociar.add(strExpedienteAux);
							}
						}
					}
				} else {
					listaExpNoAsociar.add(strExpedienteAux);
				}
			}
		}

		if (correlativoGrupo == -1 || correlativoGrupo == Integer.MIN_VALUE) {
			correlativoGrupo = obtenerCorrelativoGrupoAsociado();
			logger.info("Se crea un nuevo correlativo para el grupo="
					+ correlativoGrupo + " y se añade a la tabla 22");
		}

		// A la lista de asociar añadimos todos los expedientes que estén en el
		// grupo
		query = "SELECT NEXPEREL22 FROM AA21B22S01 WHERE CGRUPO22=?";
		Aa21b22s01DaoImpl.logger.info("SQL = " + query);
		Aa21b22s01DaoImpl.logger.info("PARAM1=" + correlativoGrupo);
		List<String> listaAux = this.jdbcTemplate.queryForList(query,
				String.class, correlativoGrupo);
		if (listaAux != null && listaAux.size() > 0) {
			for (String s : listaAux) {
				if (!listaExpAsociar.contains(s)) {
					listaExpAsociar.add(s);
					listaExpNuevosAsociar.add(s);
				}
			}
		}

		if (listaExpAsociar != null && listaExpAsociar.size() > 0) {

			Aa21b22s01DaoImpl.logger
					.info("Empieza a insertar los asociados, uno a uno");
			queryExiste = "SELECT COUNT(1) FROM AA21B22S01 WHERE CGRUPO22=? AND NEXPEREL22=?";
			query = "INSERT INTO AA21B22S01 (CGRUPO22,NEXPEREL22) VALUES (?,?)";
			for (int i = 0; i < listaExpAsociar.size(); i++) {
				String refExp = listaExpAsociar.get(i).replaceAll("-", "/");
				Aa21b22s01DaoImpl.logger.info("SQL = " + queryExiste);
				Aa21b22s01DaoImpl.logger.info("PARAM1=" + correlativoGrupo);
				Aa21b22s01DaoImpl.logger.info("PARAM2=" + refExp);
				if (this.jdbcTemplate.queryForInt(queryExiste,
						correlativoGrupo, refExp) == 0) {
					Aa21b22s01DaoImpl.logger.info("SQL = " + query);
					Aa21b22s01DaoImpl.logger.info("PARAM1=" + correlativoGrupo);
					Aa21b22s01DaoImpl.logger.info("PARAM2=" + refExp);
					this.jdbcTemplate.update(query, correlativoGrupo, refExp);
				}
			}

			// Añadimos al propio expediente en el grupo (no hace falta porque
			// ya está en la lista de asociados)
			Aa21b22s01DaoImpl.logger.info("SQL = " + query);
			Aa21b22s01DaoImpl.logger.info("PARAM1=" + correlativoGrupo);
			Aa21b22s01DaoImpl.logger.info("PARAM2=" + expediente.getRefExp());
			this.jdbcTemplate.update(query, correlativoGrupo,
					expediente.getRefExp());
		}

		ArrayList<Object> ret = new ArrayList<Object>();
		ret.add(correlativoGrupo);
		ret.add(listaExpNoAsociar);
		ret.add(listaExpNuevosAsociar);
		return ret;
	}

	public int updateAsociadosANT(ArrayList<String> listaExpAsociados,
			Aa21b20s01 expediente) {
		logger.info("Entra en updateAsociados, actualiza ls expedientes asociados de un expediente");
		Integer correlativoGrupo = 0;
		if (expediente.getGrupo() != null && !expediente.getGrupo().equals("")) {
			correlativoGrupo = Integer.valueOf(expediente.getGrupo());
			logger.info("Tiene grupo=" + correlativoGrupo);
		} else {
			correlativoGrupo = buscarGrupoExpediente(expediente);
			if (correlativoGrupo == -1) {
				correlativoGrupo = obtenerCorrelativoGrupoAsociado();
				logger.info("No tiene grupo, se crea correlativo="
						+ correlativoGrupo + " y se añade a la tabla 22");
				String query = "INSERT INTO AA21B22S01 (CGRUPO22, NEXPEREL22) VALUES (?,?)";
				Aa21b22s01DaoImpl.logger.info("SQL = " + query);
				Aa21b22s01DaoImpl.logger.info("PARAM1=" + correlativoGrupo);
				Aa21b22s01DaoImpl.logger.info("PARAM2="
						+ expediente.getRefExp());
				this.jdbcTemplate.update(query, correlativoGrupo,
						expediente.getRefExp());
			}
		}
		Aa21b22s01DaoImpl.logger
				.info("Empieza a insertar los asociados, uno a uno");
		String queryAsociados = "INSERT INTO AA21B22S01 (CGRUPO22,NEXPEREL22) VALUES (?,?)";
		for (int i = 0; i < listaExpAsociados.size(); i++) {
			String refExp = listaExpAsociados.get(i).replaceAll("-", "/");
			// String existeAsociado = listaExpAsociados.get(i);
			/*
			 * if (existeAsociado.equals("true")) { String queryAsociados =
			 * "UPDATE AA21B22S01 SET CGRUPO22 = ? WHERE NEXPEREL22 = ?";
			 * Aa21b22s01DaoImpl.logger.info("SQL = " + queryAsociados);
			 * Aa21b22s01DaoImpl.logger.info("PARAM1=" + correlativoGrupo);
			 * Aa21b22s01DaoImpl.logger.info("PARAM2=" + refExp);
			 * 
			 * this.jdbcTemplate.update(queryAsociados, correlativoGrupo,
			 * refExp);
			 * 
			 * } else {
			 */
			Aa21b22s01DaoImpl.logger.info("SQL = " + queryAsociados);
			Aa21b22s01DaoImpl.logger.info("PARAM1=" + correlativoGrupo);
			Aa21b22s01DaoImpl.logger.info("PARAM2=" + refExp);
			this.jdbcTemplate.update(queryAsociados, correlativoGrupo, refExp);
			// }
		}
		return correlativoGrupo;
	}

	// 20161117 INI - INIGO

	@Override
	public void removeAsociados(Aa21b20s01 expediente) {
		Aa21b22s01DaoImpl.logger
				.info("removeAsociados: borra los expedientes asociados de la tabla 22");
		StringBuilder query = new StringBuilder("DELETE FROM AA21B22S01 t1 ");
		StringBuilder where = new StringBuilder("");
		where.append(" WHERE t1.CGRUPO22=? and t1.NEXPEREL22!=?");
		query.append(where);
		Aa21b22s01DaoImpl.logger.info("SQL = " + query);
		Aa21b22s01DaoImpl.logger.info("PARAM1=" + expediente.getGrupo());
		Aa21b22s01DaoImpl.logger.info("PARAM1=" + expediente.getRefExp());
		this.jdbcTemplate.update(query.toString(), expediente.getGrupo(),
				expediente.getRefExp());
	}

	@Override
	public void removeAsociados(ArrayList<String> listaDesasociar,
			Aa21b20s01 expediente) {
		Aa21b22s01DaoImpl.logger
				.info("removeAsociados: borra los expedientes asociados de la tabla 22");
		StringBuilder query = new StringBuilder("DELETE FROM AA21B22S01 t1 ");
		StringBuilder where = new StringBuilder("");
		List<String> params = new ArrayList<String>();
		// where.append(" WHERE t1.CGRUPO22 = ?");
		// params.add(expediente.getGrupo());
		where.append(" WHERE ");
		for (int i = 0; i < listaDesasociar.size(); i++) {
			if (i != 0) {
				where.append(" OR ");
			}
			String refExp = listaDesasociar.get(i).replaceAll("-", "/");
			where.append(" t1.NEXPEREL22=?");
			params.add(refExp);
		}

		// where.append(")");
		query.append(where);
		Aa21b22s01DaoImpl.logger.info("SQL = " + query);
		Aa21b22s01DaoImpl.logger.info("PARAM2=" + params.toArray());
		this.jdbcTemplate.update(query.toString(), params.toArray());
	}

	@Transactional(readOnly = true)
	public Integer obtenerCorrelativoGrupoAsociado() {
		Aa21b22s01DaoImpl.logger.info("Método obtenerCorrelativoGrupoAsociado");
		StringBuffer query = new StringBuffer(
				"SELECT MAX(CGRUPO22) FROM Aa21b22s01 ");
		List<Object> params = new ArrayList<Object>();
		Aa21b22s01DaoImpl.logger.info("obtenerCorrelativoExpediente");
		Aa21b22s01DaoImpl.logger.info("SQL = " + query.toString());
		return Integer.valueOf(this.jdbcTemplate.queryForInt(query.toString(),
				params.toArray())) + 1;
	}

	/**
	 * Actualiza el código de expediente en toda la tabla
	 * 
	 * @param codexpeold
	 * @param codexpenew
	 * @return
	 */
	@Override
	public int update(String codexpeold, String codexpenew) {
		logger.info("Actualiza el código de expediente en toda la tabla");
		String query = "UPDATE AA21B22S01 SET NEXPEREL22=? WHERE NEXPEREL22=?";
		Aa21b22s01DaoImpl.logger.info("SQL = " + query);
		Aa21b22s01DaoImpl.logger.info("PARAM1=" + codexpenew);
		Aa21b22s01DaoImpl.logger.info("PARAM2=" + codexpeold);
		return this.jdbcTemplate.update(query, codexpenew, codexpeold);
	}

	/**
	 * Elimina un expediente del grupo del expediente origen.
	 * 
	 * @param expAModificar
	 *            String
	 * @param expEliminarGrupo
	 *            String
	 * @return
	 */
	@Override
	public void eliminarExpAsociadoGrupo(String expAModificar,
			String expEliminarGrupo) {
		Aa21b22s01DaoImpl.logger
				.info("eliminarExpAsociadoGrupo: borra los expedientes asociados de la tabla 22");
		StringBuilder query = new StringBuilder("DELETE FROM AA21B22S01 t1 ");
		StringBuilder where = new StringBuilder("");
		List<String> params = new ArrayList<String>();
		where.append(" WHERE t1.CGRUPO22 = ?");
		int c = this.buscarGrupoExpedienteOrig(expAModificar);
		if (c > 0) {
			params.add(c + "");
		} else {
			params.add("999999");
		}

		where.append(" AND t1.NEXPEREL22 = ?");
		params.add(expEliminarGrupo);

		query.append(where);
		Aa21b22s01DaoImpl.logger.info("SQL = " + query);
		Aa21b22s01DaoImpl.logger.info("PARAM2=" + params.toArray());
		this.jdbcTemplate.update(query.toString(), params.toArray());
	}
}