package com.softgraf.vendas.control;

import java.time.LocalDate;
import java.util.Date;
import java.util.List;
import java.util.Optional;

import com.softgraf.vendas.model.dao.ItemDAO;
import com.softgraf.vendas.model.dao.PedidoDAO;
import com.softgraf.vendas.model.dao.ProdutoDAO;
import com.softgraf.vendas.model.pojo.Cliente;
import com.softgraf.vendas.model.pojo.Item;
import com.softgraf.vendas.model.pojo.Pedido;
import com.softgraf.vendas.model.pojo.Produto;
import com.softgraf.vendas.view.TableViewHelper;

import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.ButtonType;
import javafx.scene.control.ComboBox;
import javafx.scene.control.DatePicker;
import javafx.scene.control.Label;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;

public class ControlePedido {
	
	@FXML
	private TextField txtIdPedido, txtIdCliente, txtIdProduto, txtQtde;
	@FXML
	private DatePicker calendario;
	@FXML
	private ComboBox<Cliente> cmbCliente;
	private static ComboBox<Cliente> staticCmbCliente = null;
	@FXML
	private ComboBox<Produto> cmbProduto;
	private static ComboBox<Produto> staticCmbProduto = null;
	@FXML
	private Label lblMensagem, lblTotal;
	@FXML
	private TableView<ObservableList<StringProperty>> pedidoTableView, itemTableView;
	private TableViewHelper<Pedido> tableViewHelperPedido = null;
	private TableViewHelper<Item> tableViewHelperItem = null;

	private static PedidoDAO pedidoDAO = null;
	private static ProdutoDAO produtoDAO = null;
	private ItemDAO itemDAO = null;

	// Query = consulta
	private String sqlSelectItem = "SELECT i.Produto_id AS 'ID Produto', p.Nome AS 'Produto', "
			+ "i.Quantidade AS 'Qtde', p.preco AS 'R$ Unit.', " + "Format(p.preco * i.quantidade, 2) AS 'R$ Total'"
			+ " FROM Item i, Produto p WHERE p.id=i.Produto_id AND i.Pedido_id=";

	@FXML
	public void initialize() {
		pedidoDAO = VendasPrincipal.getPedidoDAO();
		produtoDAO = VendasPrincipal.getProdutoDAO();
		itemDAO = pedidoDAO.getItemDAO();

		cmbCliente.getItems().addAll(pedidoDAO.getClienteDAO().listar());
		staticCmbCliente = cmbCliente;  
		
		cmbProduto.getItems().addAll(produtoDAO.listar());
		staticCmbProduto = cmbProduto;
		
		cmbCliente.valueProperty().addListener(new ChangeListener<Cliente>() {
			@Override
			public void changed(ObservableValue<? extends Cliente> observable, Cliente anterior, Cliente atual) {
				if (atual != null)
					txtIdCliente.setText(atual.getId().toString());
			}
		});
		
		cmbProduto.valueProperty().addListener(new ChangeListener<Produto>() {

			@Override
			public void changed(ObservableValue<? extends Produto> observable, 
												Produto anterior, Produto atual) {
				if (atual != null) 
					txtIdProduto.setText(atual.getId().toString());
			}
		});

		String sqlSelectPedido = "SELECT p.ID AS 'ID Pedido', DATE_FORMAT(p.Data, '%d/%m/%Y') AS Data, "
				+ "c.Nome AS Cliente FROM Pedido AS p, Cliente AS c " + " WHERE p.Cliente_id = c.id";

		tableViewHelperPedido = new TableViewHelper<>(pedidoTableView, pedidoDAO, sqlSelectPedido);

		pedidoTableView.setOnMouseClicked(e -> {
			String idPedido = tableViewHelperPedido.getValorSelecionado(0);
			if (idPedido != null) {

				if (e.getClickCount() == 1) {

					preencherCamposPedido(pedidoDAO.buscar(Integer.parseInt(idPedido)));

					if (tableViewHelperItem == null) {
						tableViewHelperItem = new TableViewHelper<>(itemTableView, pedidoDAO.getItemDAO(),
								sqlSelectItem + idPedido);
					} else {
						tableViewHelperItem.atualizarDados(sqlSelectItem + idPedido);
					}

					lblTotal.setText(String.valueOf(pedidoDAO.getTotalPedido(Integer.parseInt(idPedido))));
					
					itemTableView.setOnMouseClicked(ev -> {
						String idProduto = tableViewHelperItem.getValorSelecionado(0);
						String qtdeProduto = tableViewHelperItem.getValorSelecionado(2);
						
						if (idProduto != null) {
							if (ev.getClickCount() == 1) {
								preencherCamposItem(idPedido, idProduto, qtdeProduto);
							} else
								excluirItem(idPedido, idProduto);
						}
					});
					
				} else {
					excluirPedido(idPedido);
				}
			}
		});
	}

	@FXML
	public void acaoSalvarAtualizarPedido() {
		Pedido pedido= null;
		Cliente cliente = null;
		Date data = null;
		boolean sucesso = false;
		
		if (txtIdCliente.getText().isEmpty()) {
			lblMensagem.setText("Você esqueceu de selecionar o cliente!");
			return;
		} else {
			cliente = pedidoDAO.getClienteDAO().buscar(
							Integer.parseInt(txtIdCliente.getText()));
		}
		
		if (calendario.getValue() == null) {
			lblMensagem.setText("Você esqueceu de entrar com a data!");
			calendario.requestFocus();
			return;
		} else {
			data =  java.sql.Date.valueOf(calendario.getValue()); 
		}
		
		if (!txtIdPedido.getText().isEmpty()) {
			Integer id = Integer.parseInt(txtIdCliente.getText());
			pedido = pedidoDAO.buscar(id);
		}
		
		// atualiza pedido existente
		if (pedido != null) {
			pedido.setData(data);
			pedido.setCliente(cliente);
			sucesso = pedidoDAO.atualizar(pedido);
		// salva pedido novo
		} else {
			pedido = new Pedido(null, data, cliente);
			sucesso = pedidoDAO.inserir(pedido);
			lblTotal.setText("0.00");
		}
		
		if (sucesso) {
			txtIdPedido.setText(pedido.getId().toString());
			tableViewHelperPedido.atualizarDados();
			lblMensagem.setText("Dados salvos/atualizados com sucesso!");
		} else {
			lblMensagem.setText("Erro ao salvar/atualizar");
		}
	}

	@FXML
	public void acaoSalvarAtualizarItem() {
		boolean sucesso = false;
		
		if (!txtIdPedido.getText().isEmpty()) {
			
			if (!txtIdProduto.getText().isEmpty()) {
				
				if (!txtQtde.getText().isEmpty()) {
					
					int qtde = Integer.parseInt(txtQtde.getText());
					
					Integer idPedido = Integer.parseInt(txtIdPedido.getText());
					Pedido pedido = new Pedido(idPedido, null, null);
					
					Integer idProduto = Integer.parseInt(txtIdProduto.getText());
					Produto produto = new Produto(idProduto, null, null);
					
					Item item = new Item(pedido, produto, null);
					item = itemDAO.buscar(item);
					
					// atualiza item existente
					if (item != null) {
						item.setQuantidade(qtde);
						sucesso = itemDAO.atualizar(item);
					// salva item novo
					} else {
						item = new Item(pedido, produto, qtde);
						sucesso = itemDAO.inserir(item);
					}
					
					if (sucesso) {
						tableViewHelperItem.atualizarDados(sqlSelectItem + idPedido);
						lblTotal.setText(String.valueOf(pedidoDAO.getTotalPedido(idPedido)));
						lblMensagem.setText("Item salvo/atualizado com sucesso!");
					} else
						lblMensagem.setText("Erro ao salvar/atualizar");
					
				} else
					lblMensagem.setText("Faltou definir a quantidade!");
				
			} else {
				lblMensagem.setText("Faltou selecionar o produto!");
			}
			
		} else
			lblMensagem.setText("Faltou selecionar o pedido!");
		
	}

	@FXML
	public void acaoNovoPedido() {
		AbstractController.staticLimparCampos(txtIdPedido, calendario,
				txtIdCliente, cmbCliente, txtIdProduto, txtQtde, cmbProduto);
		if (tableViewHelperItem != null) {
			tableViewHelperItem.limparDados();
		}
		lblTotal.setText("0.00");
	}

	@FXML
	public void acaoNovoItem() {
		AbstractController.staticLimparCampos(txtIdProduto, txtQtde, cmbProduto);
	}

	private void preencherCamposPedido(Pedido pedido) {
		// converte Date para LocalDate
		LocalDate data = LocalDate.parse(pedido.getData().toString());
		
		txtIdPedido.setText(pedido.getId().toString());
		calendario.setValue(data);
		txtIdCliente.setText(pedido.getCliente().getId().toString());
		cmbCliente.setValue(pedido.getCliente());
		txtIdProduto.clear();
		txtQtde.clear();
		cmbProduto.setValue(null);
	}
	
	private void excluirPedido(String id) {
		AbstractController.exclusao(pedidoDAO, id, lblMensagem, tableViewHelperPedido);
	}
	
	private void preencherCamposItem(String idPedido, String idProduto, 
													String qtdeProduto) {
		txtIdProduto.setText(idProduto);
		txtQtde.setText(qtdeProduto);
		cmbProduto.setValue(produtoDAO.buscar(Integer.parseInt(idProduto)));
	}
	
	private void excluirItem(String idPedido, String idProduto) {
		Alert alerta = new Alert(AlertType.CONFIRMATION);
		alerta.setTitle("Confirmação de EXCLUSÃO");
		alerta.setHeaderText("Você quer mesmo excluir o item selecionado? ");
		alerta.setContentText("O item do pedido ID=" + idPedido + 
				"será excluido!" + "\nVocê tem certeza?");
		 Optional<ButtonType> escolha  = alerta.showAndWait();
		 
		 // se OK pressionado, o item será excluido do banco
		 if (escolha.get() == ButtonType.OK) {
			 Pedido pedido = pedidoDAO.buscar(Integer.parseInt(idPedido));
			 Produto produto = produtoDAO.buscar(Integer.parseInt(idProduto));
			 Item item = new Item(pedido, produto, null);
			 boolean apagado = pedidoDAO.getItemDAO().apagar(item);
			 if (apagado) {
				 lblMensagem.setText("Item foi removido do Banco de Dados!");
				 tableViewHelperItem.atualizarDados(sqlSelectItem + idPedido);
				 lblTotal.setText(String.valueOf(pedidoDAO.getTotalPedido(
						 				Integer.parseInt(idPedido))));
			 } else
				 lblMensagem.setText("Não foi posível excluir item do Banco de Dados.");
		 } 
	}
	
	public static void atualizarClientesProdutos() {
		
		if (staticCmbCliente != null && staticCmbProduto != null) {
			
			List<Cliente> clientes = pedidoDAO.getClienteDAO().listar();
			staticCmbCliente.setItems(FXCollections.observableArrayList(clientes));
			
			List<Produto> produtos = produtoDAO.listar();
			staticCmbProduto.setItems(FXCollections.observableArrayList(produtos));
		}
	}
	
}
