package Controllers.Stock;

import Controllers.Traitement.ParametreSystem;
import Controllers.Traitement.contro;
import Models.Categorie.CategorieDB;
import Models.Categorie.CategorieListe;
import Models.Produit.ListeProduit;
import Models.Stock.StockDB;
import javafx.scene.control.ProgressBar;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.concurrent.WorkerStateEvent;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.print.PrinterJob;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.AnchorPane;
import javafx.util.Callback;

/**
 * @author Maher Ben Tili
 */
public class EtatStockCategorieController implements Initializable {

    @FXML private AnchorPane AnchorPaneEtatStockCategorie;
    
    @FXML private ProgressBar BarLoading;
    
    @FXML private ComboBox ComboLocale;
    
    @FXML private TextField TextFieldCategory;
    @FXML private TextField TextFieldReference;
    @FXML private TextField TextFieldDesignation;
    
    @FXML private TableView<CategorieListe> TableViewCategorie ;
    @FXML private TableColumn<CategorieListe, String> TabColNomCategorie;
    @FXML private TableColumn<CategorieListe, String> TabColQuantiteCategorie;
    @FXML private TableColumn<CategorieListe, Boolean> TabColDetailAction ;
   
    @FXML private TableView<ListeProduit> TableViewProduit ;
    @FXML private TableColumn<ListeProduit, String> TabColProduitReference;
    @FXML private TableColumn<ListeProduit, String> TabColProduitDesignation;
    @FXML private TableColumn<ListeProduit, String> TabColProduitQuantite;
    @FXML private TableColumn<ListeProduit, Boolean> TabColProduitDetailAction ;
    
    @FXML private Button BtnPrintAllProduit;
    @FXML private Button BtnPrintAllCategory;
    @FXML private Button BtnPrintSelectProduit;
    
    String StringLocale = ParametreSystem.NomLocalPC;
    String StrSeleCategory = "";
    
    private Service<Void> ThreadEtatStockCategorie;
    
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        
        TabColNomCategorie.setCellValueFactory(new PropertyValueFactory<CategorieListe, String>("Nom"));
        
        TabColQuantiteCategorie.setStyle( "-fx-alignment: CENTER; -fx-font-weight:bold; -fx-font-size: 10pt;");
        TabColQuantiteCategorie.getStyleClass().add("Center");
        TabColQuantiteCategorie.setCellValueFactory(new PropertyValueFactory<CategorieListe, String>("Quantite"));
        
        TabColDetailAction.setStyle( "-fx-alignment: CENTER; -fx-font-weight:bold; -fx-font-size: 10pt;");
        TabColDetailAction.getStyleClass().add("Center");
        TabColDetailAction.setCellFactory(new Callback<TableColumn<CategorieListe, Boolean>, TableCell<CategorieListe, Boolean>>() {
          @Override 
          public TableCell<CategorieListe, Boolean> call(TableColumn<CategorieListe, Boolean> personBooleanTableColumn) {
            return new ButtonCellCategorie();
          }
        });
        
        //Liste des Locales
        ComboLocale.getItems().addAll(new StockDB().getAllListLocal());
        ComboLocale.getSelectionModel().select(ParametreSystem.NomLocalPC);
        
        ComboLocale.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                StringLocale = ComboLocale.getValue().toString();
                SearchCategorie(StringLocale, TextFieldCategory.getText());
                TableViewProduit.setItems(null);
            }
        });
        
        TextFieldCategory.setOnKeyReleased(new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent ke) {
                if (ke.getCode().equals(KeyCode.ENTER)) {
                    SearchCategorie(StringLocale, TextFieldCategory.getText());
                }
            }
        });
        
        SearchCategorie(StringLocale, "");
        
        
        
        /******************* List des Produits******************************/
        
        TabColProduitReference.setCellValueFactory(new PropertyValueFactory<ListeProduit, String>("reference"));
        TabColProduitDesignation.setCellValueFactory(new PropertyValueFactory<ListeProduit, String>("designation"));
        TabColProduitQuantite.setCellValueFactory(new PropertyValueFactory<ListeProduit, String>("quantite"));
        TabColProduitQuantite.setStyle( "-fx-alignment: CENTER; -fx-font-weight:bold; -fx-font-size: 10pt;");
        TabColProduitQuantite.getStyleClass().add("Center");
        
        TabColProduitDetailAction.setStyle( "-fx-alignment: CENTER; -fx-font-weight:bold; -fx-font-size: 10pt;");
        TabColProduitDetailAction.getStyleClass().add("Center");
        TabColProduitDetailAction.setCellFactory(new Callback<TableColumn<ListeProduit, Boolean>, TableCell<ListeProduit, Boolean>>() {
          @Override 
          public TableCell<ListeProduit, Boolean> call(TableColumn<ListeProduit, Boolean> personBooleanTableColumn) {
            return new ButtonCellProduit();
          }
        });
        
        TextFieldReference.setOnKeyReleased(new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent ke) {
                if (ke.getCode().equals(KeyCode.ENTER)) {
                   SearchProduits("", TextFieldReference.getText(), ""); 
                }
                
            }
        });
        
	TextFieldDesignation.setOnKeyReleased(new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent ke) {
                if (ke.getCode().equals(KeyCode.ENTER)) {
                    SearchProduits("", "", TextFieldDesignation.getText());
                }
            }
        });
       
        BtnPrintAllProduit.setOnAction(new EventHandler<ActionEvent>(){ //Action when the button is pressed
            @Override
            public void handle(ActionEvent t) {
                PrintAllProduit();
            }
        });
        
        BtnPrintAllCategory.setOnAction(new EventHandler<ActionEvent>(){ //Action when the button is pressed
            @Override
            public void handle(ActionEvent t) {
                PrintAllCategorie();
            }
        });
        
        BtnPrintSelectProduit.setOnAction(new EventHandler<ActionEvent>(){ //Action when the button is pressed
            @Override
            public void handle(ActionEvent t) {
                PrintSelectProduit();
            }
        });
        
    }    
    
    
    
    
    /**
     * Print All Produit
     */
    private void PrintAllProduit() {
        try {
            ObservableList<ListeProduit> listProduits = new StockDB().getProduitInStock(StringLocale, "", "", "");
            PrinterJob job = PrinterJob.createPrinterJob();
            int SizeListProduit = listProduits.size();
            int total = SizeListProduit / 25 + 1 ;
            int page = 0;
            for (int i=0; i<SizeListProduit; i+=25){
                ObservableList<ListeProduit> listProdTemp = FXCollections.observableArrayList();
                for (int j=i; (j<(i+25)) && (j<SizeListProduit); j++){
                    listProdTemp.add(listProduits.get(j));
                }
                FXMLLoader fxmlLoaderAllProduit = new FXMLLoader(getClass().getResource("/Views/Stock/PrintAllProduit.fxml"));
                final Node ParentFxmlAllProduit = (Node)fxmlLoaderAllProduit.load();
                PrintAllProduitController PrintStockProduit = fxmlLoaderAllProduit.getController();
                page++;
                PrintStockProduit.setProduits(listProdTemp, StringLocale, page+"/"+total);
                job.printPage(ParentFxmlAllProduit);
            }
            job.endJob();
        } catch (IOException ex) {
            System.err.println("FactureFrsGestionController PrintAllProduit ! \n"+ex.getMessage());
        }
    }


    /**
     * Print tous Categories
     */
    private void PrintAllCategorie() {
        try {
            ObservableList<CategorieListe> listCategorie = new CategorieDB().GetCategorie(StringLocale, "");
           
            PrinterJob jobCate = PrinterJob.createPrinterJob();
            int SizeListCategory = listCategorie.size();
            int total = SizeListCategory / 25 + 1 ;
            int page = 0;
            for (int i=0; i<SizeListCategory; i+=25){
                ObservableList<CategorieListe> listCateTemp = FXCollections.observableArrayList();
                for (int j=i; (j<(i+25)) && (j<SizeListCategory); j++){
                    listCateTemp.add(listCategorie.get(j));
                }
                FXMLLoader fxmlLoaderAllCategory = new FXMLLoader(getClass().getResource("/Views/Stock/PrintAllCategorie.fxml"));
                final Node ParentFxmlAllCategory = (Node)fxmlLoaderAllCategory.load();
                PrintAllCategorieController PrintStockAllCategory = fxmlLoaderAllCategory.getController();
                page++;
                PrintStockAllCategory.setCategories(listCateTemp, StringLocale, page+"/"+total);
                jobCate.printPage(ParentFxmlAllCategory);
            }
            jobCate.endJob();
        } catch (IOException ex) {
            System.err.println("FactureFrsGestionController PrintAllProduit ! \n"+ex.getMessage());
        }
    }
    
    
    
    /**
     * Print Select Produit
     */
    private void PrintSelectProduit() {
        try {
            ObservableList<ListeProduit> listSeleProduits = null;
            contro clt = new contro();
            int SizeListSeleProduit = 0;
            int total = 0;
            if(!clt.isStringNull(StrSeleCategory)){
               listSeleProduits = new StockDB().getProduitInStock(StringLocale, StrSeleCategory, "", "");
               SizeListSeleProduit = listSeleProduits.size();
               total = SizeListSeleProduit / 25 + 1 ;
            }
            PrinterJob job = PrinterJob.createPrinterJob();
            int page = 0;
            for (int i=0; i<SizeListSeleProduit; i+=25){
                ObservableList<ListeProduit> listProdTemp = FXCollections.observableArrayList();
                for (int j=i; (j<(i+25)) && (j<SizeListSeleProduit); j++){
                    listProdTemp.add(listSeleProduits.get(j));
                }
                FXMLLoader fxmlLoaderAllProduit = new FXMLLoader(getClass().getResource("/Views/Stock/PrintSelProduit.fxml"));
                final Node ParentFxmlAllProduit = (Node)fxmlLoaderAllProduit.load();
                PrintSelProduitController PrintStockProduit = fxmlLoaderAllProduit.getController();
                page++;
                PrintStockProduit.setProduits(listProdTemp, StringLocale, StrSeleCategory, page+"/"+total);
                job.printPage(ParentFxmlAllProduit);
            }
            job.endJob();
        } catch (IOException ex) {
            System.err.println("FactureFrsGestionController PrintAllProduit ! \n"+ex.getMessage());
        }
    }
    
    /*private void SearchCategorie(final String Local, final String NomCategory){
        
        BarLoading.setVisible(true);
        TableViewCategorie.setItems(null);
        
        // Create a Runnable
        Runnable task = new Runnable(){
            public void run(){
                Platform.runLater(new Runnable(){
                    @Override
		    public void run(){
                        TableViewCategorie.setItems(new CategorieDB().GetCategorie(Local, NomCategory));
                        BarLoading.setVisible(false);
		    }
		});	
            }
	};

	Thread backgroundThread = new Thread(task); // Run the task in a background thread
	backgroundThread.setDaemon(true);   // Terminate the running thread if the application exits
	backgroundThread.start();   // Start the thread
    }*/
    private void SearchCategorie(final String Local, final String NomCategory){
        
        BarLoading.setVisible(true);
        
        TableViewCategorie.setItems(null);
        
        ThreadEtatStockCategorie = new Service<Void>(){
            @Override
            protected Task<Void> createTask(){
                return new Task<Void>(){
                    @Override
                    protected Void call() throws Exception{
                        TableViewCategorie.setItems(new CategorieDB().GetCategorie(Local, NomCategory));
                        return null;
                    }
                };
            }
	};
        
        ThreadEtatStockCategorie.setOnSucceeded(new EventHandler<WorkerStateEvent>(){
            @Override
            public void handle(WorkerStateEvent event){
                BarLoading.setVisible(false);
            }
        });
        ThreadEtatStockCategorie.start();
    }
    
    
    private void SearchProduits(final String Categorie, final String Reference, final String Designation)
    {
        BarLoading.setVisible(true);
        
        TableViewProduit.setItems(null);
        
        ThreadEtatStockCategorie = new Service<Void>(){
            @Override
            protected Task<Void> createTask(){
                return new Task<Void>(){
                    @Override
                    protected Void call() throws Exception{
                        TableViewProduit.setItems(new StockDB().getProduitInStock(StringLocale, Categorie, Reference, Designation));
                        return null;
                    }
                };
            }
	};
        
        ThreadEtatStockCategorie.setOnSucceeded(new EventHandler<WorkerStateEvent>(){
            @Override
            public void handle(WorkerStateEvent event){
                BarLoading.setVisible(false);
            }
        });
        ThreadEtatStockCategorie.start();
    }
    
    private class ButtonCellCategorie extends TableCell<CategorieListe, Boolean> {
        
        final Button cellButton = new Button();

        ButtonCellCategorie(){
            cellButton.getStyleClass().add("btn-icon-primary");
            Image coffeeImage = new Image(getClass().getResourceAsStream("/Public/icon/detailbutton.png"));
            ImageView buttonGraphic = new ImageView();
            buttonGraphic.setImage(coffeeImage);
            cellButton.setGraphic(buttonGraphic);

            //Action when the button is pressed
            cellButton.setOnAction(new EventHandler<ActionEvent>(){
                @Override
                public void handle(ActionEvent t) {
                    
                    CategorieListe ListCategorie = (CategorieListe)getTableRow().getItem();
                    StrSeleCategory = ListCategorie.getNom();
                    SearchProduits(ListCategorie.getNom(), "", "");
                    
                }
            });
        }

        //Display button if the row is not empty
        @Override
        protected void updateItem(Boolean t, boolean empty) {
            if(!empty){
                setGraphic(cellButton);
            } else {
                setGraphic(null);
            }
        }
    }
    
    private class ButtonCellProduit extends TableCell<ListeProduit, Boolean> {
        
        final Button cellButton = new Button();
        
        ButtonCellProduit(){
            cellButton.getStyleClass().add("btn-icon-primary");
            Image coffeeImage = new Image(getClass().getResourceAsStream("/Public/icon/detailbutton.png"));
            ImageView buttonGraphic = new ImageView();
            buttonGraphic.setImage(coffeeImage);
            cellButton.setGraphic(buttonGraphic);

            //Action when the button is pressed
            cellButton.setOnAction(new EventHandler<ActionEvent>(){
                @Override
                public void handle(ActionEvent t) {
                    ListeProduit produit = (ListeProduit)getTableRow().getItem();
                    try {
                        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/Views/Stock/MouvementStock.fxml"));
                        Parent NodeMouvementStock = (Parent)fxmlLoader.load();

                        MouvementStockController MouvementStock = fxmlLoader.getController();
                        MouvementStock.SetData(produit.getReference(), produit.getDesignation(), StringLocale);

                        AnchorPaneEtatStockCategorie.getChildren().clear();
                        AnchorPaneEtatStockCategorie.getChildren().add(NodeMouvementStock);
                    
                    } catch (Exception ex) {
                           System.err.println(ex.getMessage());
                    }
                }
            });
        }

        //Display button if the row is not empty
        @Override
        protected void updateItem(Boolean t, boolean empty) {
            if(!empty){
                setGraphic(cellButton);
            } else {
                setGraphic(null);
            }
        }
    }
    
}



    