package com.softgraf.control;

import static com.softgraf.control.Principal.clienteDAO;
import static com.softgraf.control.Sistema.*;

import java.util.Arrays;
import java.util.Optional;

import com.softgraf.model.Aceitar;
import com.softgraf.model.ClienteProperty;
import com.softgraf.model.Cnpj;
import com.softgraf.model.Cpf;
import com.softgraf.model.CpfCnpj;

import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.print.PageLayout;
import javafx.print.PageOrientation;
import javafx.print.Paper;
import javafx.print.Printer;
import javafx.print.PrinterJob;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.control.RadioButton;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.ToggleGroup;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.input.MouseButton;

public class ControleRelatorioClientes {

	@FXML
	private TableView<ClienteProperty> tableView;
	@FXML
	private TableColumn<ClienteProperty, Integer> colCodigo;
	@FXML
	private TableColumn<ClienteProperty, Character> colTipo;
	@FXML
	private TableColumn<ClienteProperty, String> colNome, colCpfCnpj, colTelefone, colCidade, colEstado;
	@FXML
	private RadioButton radCodigo, radNome, radCpf, radCnpj;
	@FXML
	private TextField txtCodigo, txtNome, txtCpf, txtCnpj, txtMaxLinhas;
	@FXML
	private Button btnImprimir, btnRelatorio, btnExcluir;
	private ToggleGroup grupo = new ToggleGroup();

	@FXML
	public void initialize(){
		colCodigo.setCellValueFactory(new PropertyValueFactory<>("codigo"));
		colTipo.setCellValueFactory(new PropertyValueFactory<>("tipo"));
		colNome.setCellValueFactory(new PropertyValueFactory<>("nome"));
		colCpfCnpj.setCellValueFactory(new PropertyValueFactory<>("cpfCnpj"));
		colTelefone.setCellValueFactory(new PropertyValueFactory<>("telefone"));
		colCidade.setCellValueFactory(new PropertyValueFactory<>("cidade"));
		colEstado.setCellValueFactory(new PropertyValueFactory<>("estado"));
		
		tableView.setOnMouseClicked(e -> {
			// duplo clique esquerdo = edita cadastro
			if (e.getButton() == MouseButton.PRIMARY && e.getClickCount() > 1)
				fireMenuItemCliente(Modo.ALTERACAO);
			// clique botão direito = visualizar cadastro
			else if (e.getButton() == MouseButton.SECONDARY)
				fireMenuItemCliente(Modo.CONSULTA);
		});
		
		Arrays.asList(radCodigo, radNome, radCpf, radCnpj)
			.forEach(btn -> btn.setToggleGroup(grupo));
		radCodigo.setSelected(true);
		
		txtCodigo.setOnKeyTyped(e -> Aceitar.apenasInteirosPositivos(e, 6));
		txtNome.focusedProperty().addListener(Void -> 
				txtNome.setText(txtNome.getText().toUpperCase().trim()));
		
		txtCpf.setOnKeyTyped(e -> Aceitar.apenasInteirosPositivos(e, Cpf.MAX));
		txtCpf.focusedProperty().addListener(Void -> CpfCnpj.formatar(txtCpf, true));
		
		txtCnpj.setOnKeyTyped(e -> Aceitar.apenasInteirosPositivos(e, Cnpj.MAX));
		txtCnpj.focusedProperty().addListener(Void -> CpfCnpj.formatar(txtCnpj, false));
		
		txtMaxLinhas.setText("100");
		txtMaxLinhas.setOnKeyTyped(e -> Aceitar.apenasInteirosPositivos(e, 6));
		txtMaxLinhas.focusedProperty().addListener(Void -> validarMaxLinhas());
		
		btnImprimir.setOnAction(e -> imprimir(e));
		btnRelatorio.setOnAction(e -> relatorio());
		btnExcluir.setOnAction(e -> excluir());
		
		Platform.runLater(() ->	tableView.setItems(clienteDAO.listarPorId(1, clienteDAO.contar())));
	}

	
	private void validarMaxLinhas(){
		String txtMax = txtMaxLinhas.getText().trim();
		if (txtMax.length() > 0 && Integer.parseInt(txtMax) < 1){
			txtMaxLinhas.setText("");
			dlgErro.setHeaderText("Máximo de linhas deve ser MAIOR que 0 (zero)!");
			dlgErro.showAndWait();
			txtMaxLinhas.requestFocus();
		}
	}
	
	private void relatorio(){
		int max; // máximo de registros para trazer da tabela cliente
		if (txtMaxLinhas.getText().isEmpty() || 
				(max = Integer.parseUnsignedInt(txtMaxLinhas.getText())) == 0)
			max = clienteDAO.contar();
		
		final int quant = max;  
		
		if (radCodigo.isSelected()){
			int cod;
			if (txtCodigo.getText().isEmpty() 
					|| (cod = Integer.parseUnsignedInt(txtCodigo.getText())) == 0)
				cod = 1;
			final int id = cod;
			Platform.runLater(() -> tableView.setItems(clienteDAO.listarPorId(id, quant)));
			
		} else if (radNome.isSelected()){
			String nome = txtNome.getText().trim();
			Platform.runLater(() -> tableView.setItems(clienteDAO.listarPorNome(nome, quant)));
			
		} else if (radCpf.isSelected()){
			String cpf = txtCpf.getText().trim();			
			Platform.runLater(() -> tableView.setItems(clienteDAO.listarPorCpf(cpf, quant)));
			
		} else if (radCnpj.isSelected()){
			String cnpj = txtCnpj.getText().trim();			
			Platform.runLater(() -> tableView.setItems(clienteDAO.listarPorCnpj(cnpj, quant)));
		}
	}
	
	private void excluir(){
		ClienteProperty cliente = tableView.getSelectionModel().getSelectedItem();
		if (cliente == null){
			dlgInfo.setContentText("Nenhum cliente selecionado para exclusão!");
			dlgInfo.showAndWait();
		} else {
			dlgConfirma.setContentText("Apaga o cliente selecionado?");
			Optional<ButtonType> resp = dlgConfirma.showAndWait();
			if (resp.get() == ButtonType.OK){
				
				if (clienteDAO.remover(cliente.getCodigo())){
					dlgInfo.setHeaderText("SUCESSO!");
					dlgInfo.setContentText("Relatório será atualizado...");
					dlgInfo.showAndWait();
					relatorio();
				} else {
					dlgErro.setContentText("Erro ao excluir cliente");
					dlgErro.showAndWait();
				}
			}
		}
	}
	
	private void imprimir(ActionEvent e){
		Printer impressoa = Printer.getDefaultPrinter();
		PrinterJob job = PrinterJob.createPrinterJob(impressoa);
		PageLayout pagina = impressoa.createPageLayout(Paper.A4, 
				PageOrientation.LANDSCAPE, Printer.MarginType.DEFAULT);
		
		TableView<ClienteProperty> tablePrint = new TableView<>();
		tablePrint.getColumns().addAll(tableView.getColumns());
		tablePrint.setItems(tableView.getItems());
		double escalaX = pagina.getPrintableWidth() / tableView.getWidth();
		double escalaY = pagina.getPrintableHeight() / tableView.getHeight();
		tablePrint.setScaleX(escalaX);
		tablePrint.setScaleY(escalaY);
		tablePrint.setTranslateX(-60.0);
		tablePrint.setTranslateY(40.0);
		
		if (job != null){
			boolean showDialog = job.showPrintDialog(Principal.palco.getOwner());
			if (showDialog){
				boolean sucesso = job.printPage(pagina, tablePrint);
				if (sucesso){
					job.endJob();
				}
			}
			
		} else {
			dlgErro.setHeaderText("Erro ao criar PrinterJob");
			dlgErro.setContentText("PrinterJob.createPrinterJob(printer)");
			dlgErro.showAndWait();
		}
	}
	
	private void fireMenuItemCliente(Modo modo){
		ClienteProperty cliente = tableView.getSelectionModel().getSelectedItem();
		ControleCliente.setModo(cliente, modo);
		// dispara um evento sobre o menu Cadastrar Cliente
		findMenuItem("cadastrar", "cliente").fire();
		
		
	}
}
