package br.com.senacagil.springmvc.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;

import br.com.senacagil.springmvc.business.Professor;
import br.com.senacagil.springmvc.business.Turma;
import br.com.senacagil.springmvc.util.DBConexao;

public class TurmaDAO {
	private DBConexao db = null;

	private ProfessorDAO professorDao = null;

	public TurmaDAO(ProfessorDAO professorDao, DBConexao dbConexao) {
		super();
		this.professorDao = professorDao;
		this.db = dbConexao;
	}

	public String adicionarTurma(Turma turma) {
		Boolean existe = false;
		String msg = "Turma Cadastrada com Sucesso";

		try {
			// Recupera conexão com o banco
			Connection con = db.getConnection();

			// Monta base do SQL
			String sql = "SELECT * FROM turma WHERE codigo = ?";

			// Cria um statement
			PreparedStatement ps = con.prepareStatement(sql);

			// Atribui parametros
			ps.setString(1, turma.getCodigo());

			// Executa o sql
			ResultSet rs = ps.executeQuery();

			if (rs.next()) {
				existe = true;
				msg = "Código já existe";
			}
			// Termina o statement
			rs.close();
			ps.close();

			if (!existe) {
				// Monta base do SQL
				sql = "INSERT INTO turma (codigo, nome, carga_horaria) VALUES (?, ?, ?)";

				// Cria um statement
				ps = con.prepareStatement(sql);

				// Atribui os parametros
				ps.setString(1, turma.getCodigo());
				ps.setString(2, turma.getNome());
				if (turma.getCargaHoraria() != null) {
					ps.setInt(3, turma.getCargaHoraria());
				} else {
					ps.setNull(3, Types.INTEGER);
				}

				// Executa o sql
				ps.executeUpdate();

				// Termina o statement
				ps.close();
			}
		} catch (SQLException e) {
			e.printStackTrace();
			msg = "Erro na execução do SQL. Contacte o Administrador";
		}
		return msg;

	}

	public String removerTurma(Long id) {
		// Monta base do SQL
		String sql = "DELETE FROM turma WHERE id = ?";
		String msg = "Turma deletada com sucesso";

		try {
			// Recupera conexão com o banco
			Connection con = db.getConnection();

			// Cria um statement
			PreparedStatement ps = con.prepareStatement(sql);

			// Atribui parametros
			ps.setLong(1, id);

			// Executa o sql
			ps.executeUpdate();

			// Termina o statement
			ps.close();
		} catch (SQLException e) {
			e.printStackTrace();
			msg = "Erro na execução do SQL. Contacte o Administrador";
		}
		return msg;
	}

	public Turma leTurma(Long id) {
		Turma turma = null;
		// Monta base do SQL
		String sql = "SELECT * FROM turma WHERE id = ?";

		// Recupera conexão com o banco
		Connection con = db.getConnection();

		try {
			// Cria um statement
			PreparedStatement ps = con.prepareStatement(sql);

			ps.setLong(1, id);

			// Executa o sql
			ResultSet rs = ps.executeQuery();

			// Direciona o ResultSet para o primeiro registro
			if (rs.next()) {

				// Monta o Turma
				turma = montaTurma(rs);
			}

			// Termina o resultset e o statement
			rs.close();
			ps.close();

			// Retorna o Turma
			return turma;
		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		}
	}

	public List<Turma> listarTurmas() {
		// Monta base do SQL
		String sql = "SELECT * FROM turma ORDER BY nome";

		try {
			// Recupera conexão com o banco
			Connection con = db.getConnection();

			// Cria um statement
			PreparedStatement ps = con.prepareStatement(sql);

			// Executa o sql
			ResultSet rs = ps.executeQuery();

			// Cria objeto de Lista
			List<Turma> turmas = new ArrayList<Turma>();

			// Direciona o ResultSet para o primeiro registro
			while (rs.next()) {
				Turma turma = montaTurma(rs);
				turmas.add(turma);
			}

			// Termina o resultset e o statement
			rs.close();
			ps.close();

			// Retorna a lista
			return turmas;
		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		}
	}

	public List<Turma> listarTurmasPorNome(String nome) {
		// Monta base do SQL
		String sql = "SELECT * FROM turma WHERE nome LIKE ?";

		try {
			// Recupera conexão com o banco
			Connection con = db.getConnection();

			// Cria um statement
			PreparedStatement ps = con.prepareStatement(sql);

			ps.setString(1, "%" + nome.trim() + "%");

			// Executa o sql
			ResultSet rs = ps.executeQuery();

			// Cria objeto de Lista
			List<Turma> turmas = new ArrayList<Turma>();

			// Direciona o ResultSet para o primeiro registro
			while (rs.next()) {
				Turma turma = montaTurma(rs);
				turmas.add(turma);
			}

			// Termina o resultset e o statement
			rs.close();
			ps.close();

			// Retorna a lista
			return turmas;
		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		}
	}

	private Turma montaTurma(ResultSet rs) throws SQLException {
		Turma turma = new Turma();

		turma.setId(rs.getLong("id"));
		turma.setCodigo(rs.getString("codigo"));
		turma.setNome(rs.getString("nome"));
		turma.setCargaHoraria(rs.getInt("carga_horaria"));

		return turma;
	}

	public String atualizaTurma(Turma turma) {
		// Monta base do SQL
		String sql = "UPDATE turma SET codigo = ?, nome = ?, carga_horaria = ? WHERE id = ?";
		String msg = "Turma alterada com sucesso.";

		// Adiciona valores do Turma

		try {
			// Recupera conexão com o banco
			Connection con = db.getConnection();

			// Cria um statement
			PreparedStatement ps = con.prepareStatement(sql);

			ps.setString(1, turma.getCodigo());
			ps.setString(2, turma.getNome());
			ps.setInt(3, turma.getCargaHoraria());
			ps.setLong(4, turma.getId());
			// Executa o sql
			ps.executeUpdate();

			// Termina o statement
			ps.close();
		} catch (SQLException e) {
			e.printStackTrace();
			msg = "Erro na execução do SQL. Contacte o Administrador";

		}
		return msg;
	}

	public List<Turma> listarTurmasComProfessor() {
		// Monta base do SQL
		String sql = "SELECT * FROM turma WHERE id_professor IS NOT NULL ORDER BY NOME";

		try {
			// Recupera conexão com o banco
			Connection con = db.getConnection();

			// Cria um statement
			PreparedStatement ps = con.prepareStatement(sql);

			// Executa o sql
			ResultSet rs = ps.executeQuery();

			// Cria objeto de Lista
			List<Turma> turmas = new ArrayList<Turma>();

			// Direciona o ResultSet para o primeiro registro
			while (rs.next()) {
				Turma turma = montaTurma(rs);
				Professor professor = professorDao.leProfessor(rs
						.getInt("id_professor"));
				turma.setProfessor(professor);
				turmas.add(turma);
			}

			// Termina o resultset e o statement
			rs.close();
			ps.close();

			// Retorna a lista
			return turmas;
		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		}
	}

	public List<Turma> listarTurmasSemProfessor() {
		// Monta base do SQL
		String sql = "SELECT * FROM turma WHERE id_professor IS NULL ORDER BY NOME";

		try {
			// Recupera conexão com o banco
			Connection con = db.getConnection();

			// Cria um statement
			PreparedStatement ps = con.prepareStatement(sql);

			// Executa o sql
			ResultSet rs = ps.executeQuery();

			// Cria objeto de Lista
			List<Turma> turmas = new ArrayList<Turma>();

			// Direciona o ResultSet para o primeiro registro
			while (rs.next()) {
				Turma turma = montaTurma(rs);
				turmas.add(turma);
			}

			// Termina o resultset e o statement
			rs.close();
			ps.close();

			// Retorna a lista
			return turmas;
		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		}
	}

	public String alocarProfessor(Long idTurma, Long idProfessor) {
		// Monta base do SQL
		String sql = "UPDATE turma SET id_professor = ? WHERE id = ?";
		String msg = "Professor alocado na turma com sucesso.";

		// Adiciona valores do Turma

		try {
			// Recupera conexão com o banco
			Connection con = db.getConnection();

			// Cria um statement
			PreparedStatement ps = con.prepareStatement(sql);

			ps.setLong(1, idProfessor);
			ps.setLong(2, idTurma);
			// Executa o sql
			ps.executeUpdate();

			// Termina o statement
			ps.close();
		} catch (SQLException e) {
			e.printStackTrace();
			msg = "Erro na execução do SQL. Contacte o Administrador";

		}
		return msg;
	}

	public String desalocarProfessor(Long idTurma) {
		// Monta base do SQL
		String sql = "UPDATE turma SET id_professor = NULL WHERE id = ?";
		String msg = "Professor desalocado da turma com sucesso.";

		// Adiciona valores do Turma

		try {
			// Recupera conexão com o banco
			Connection con = db.getConnection();

			// Cria um statement
			PreparedStatement ps = con.prepareStatement(sql);

			ps.setLong(1, idTurma);
			// Executa o sql
			ps.executeUpdate();

			// Termina o statement
			ps.close();
		} catch (SQLException e) {
			e.printStackTrace();
			msg = "Erro na execução do SQL. Contacte o Administrador";

		}
		return msg;
	}

}
