package com.softgraf.vendas.model.dao.abstrato;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import com.softgraf.vendas.model.dao.Conexao;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;

// Representa um CRUD genérico  (Create Read Update Delete)
// Um DAO precisa, pelo menos, fazer as operações de CRUD 
abstract public class AbstractGenericDAO<G> {

	final protected Connection dbConnection;
	
	// construtor
	public AbstractGenericDAO(Conexao conexao) {
		this.dbConnection = conexao.getConexao();
	}
	
	abstract public void criarTabela();
	
	abstract public boolean inserir(G pojo);
	
	abstract public boolean apagar(G pojo);
	
	abstract public boolean atualizar(G pojo);
	
	abstract public G buscar(Integer id);
	
	abstract public G buscar(G pojo);
	
	abstract public G buscar(String campo);
	
	abstract public List<G> listar();
	
	public List<String> listarColunas(String sqlSelect){
		List<String> colunas = new ArrayList<>(); 
		
		try {
			Statement cmd = dbConnection.createStatement();
			ResultSetMetaData metaDados = cmd.executeQuery(sqlSelect).getMetaData();

			for (int i=1; i<= metaDados.getColumnCount(); i++){
				String label = metaDados.getColumnLabel(i);
//				String tipo = metaDados.getColumnTypeName(i);
//				int tamanho = metaDados.getColumnDisplaySize(i);
				colunas.add(label);
			}
			
			cmd.close();
			
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		return colunas;
	}
	
	
	public ObservableList<ObservableList<StringProperty>> listarDados(String sqlSelect){
		ObservableList<ObservableList<StringProperty>> listaDados = FXCollections.observableArrayList();
		
		try {
			Statement cmd = dbConnection.createStatement();
			ResultSet rs = cmd.executeQuery(sqlSelect);
			
			while (rs.next()){
				ObservableList<StringProperty> linha = FXCollections.observableArrayList();
				for (int i=1; i<= rs.getMetaData().getColumnCount(); i++){
					linha.add(new SimpleStringProperty(rs.getString(i)));
				}
				listaDados.add(linha);
			}
			
			cmd.close();
			
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		return listaDados;
	}
	
	// retorna o último ID inserido na tabela ou NULL
	protected Integer ultimoID(String tabela){
		try {
			ResultSet rs =  dbConnection.createStatement().executeQuery("SELECT MAX(id) as id FROM " + tabela);
			
			if (rs.next())
				return rs.getInt("id");
			else
				return null;
			
		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		}
	}
}
