package Controllers.Produit;

import Models.Produit.Produit;
import Controllers.DevisClt.DevisAjouterController;
import Controllers.Traitement.MyWindow;
import Models.Categorie.CategorieDB;
import Models.Produit.ProduitDB;
import Models.User.User;
import javafx.scene.control.ProgressBar;
import java.io.IOException;
import org.apache.log4j.Logger;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
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.scene.Group;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.Label;
import javafx.scene.control.RadioButton;
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.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.StackPane;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import org.controlsfx.control.textfield.TextFields;

/**
 * FXML Controller class
 * @author Maher Ben Tili
 */
public class RechercherProduitController {

    Logger logger = Logger.getLogger(RechercherProduitController.class.getName());
    
    @FXML public AnchorPane anchorpane ;
    
    @FXML private ProgressBar ProgressBarProduit;
    
    @FXML private Button ButtonSearchProduit;
    
    @FXML private Text ActuellePage ;
    @FXML private Text NbrPage ;
    @FXML private Group nextgroupe ;
    @FXML private Group avancergroupe ;
    @FXML private Group lastgroupe ;        
    @FXML private Group retourgroupe ;
    @FXML private Label LabelCount ;
    @FXML private ChoiceBox NbrLigne ;
    
    @FXML private TextField GestionProduitReference ;
    @FXML private TextField GestionProduitDesignation;
    @FXML private TextField GestionProduitMarque;
    @FXML private TextField GestionProduitCategorie;
    
    @FXML private TableView<Produit> TableViewListeGestionProduit ;
    
    @FXML private TableColumn<Produit ,String> TabColReference;
    @FXML private TableColumn<Produit ,String> TabColDesignaton;
    @FXML private TableColumn<Produit ,String> TabColMarque ;
    @FXML private TableColumn<Produit ,String> TabColCategorie;
    @FXML private TableColumn<Produit ,String> TabColPrixAchatTTC;
    @FXML private TableColumn<Produit ,String> TabColPrixVenteTTC;
    @FXML private TableColumn<Produit ,String> TabColQuantite;
    @FXML public  TableColumn<Produit ,String> TabColAction ;
    
    @FXML private AnchorPane PaneStockNegaNon;
    @FXML private Text TextEnStock;
    @FXML private RadioButton StockNegaOui;
    @FXML private RadioButton StockNegaNon;
    
    public Node nodeFxml ;
    
    private Boolean StockNegatif = false; 
    
    ObservableList cursors = FXCollections.observableArrayList("10","15","20");
    private Integer nbrligne = 10 ;
    private Integer totalcount = 0;
    private Integer nbrpage = 0;
    private Integer actuellepage = 1;
    Integer position = 0;
    
    public static String refprod ;
    
    public Object[] ArrayObjectDataSave = new Object[10];
    
    private Service<Void> ThreadSearchRerchecheProduit;
    
    
    public RechercherProduitController(Boolean TypePrixTTC) { //TypePrixTTC true Vente | false Achat
        
        try {
            FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/Views/Produit/RechercherProduit.fxml"));
            fxmlLoader.setController(this);
            nodeFxml = (Node) fxmlLoader.load();
            
            NbrLigne.setItems(cursors);
            NbrLigne.getSelectionModel().selectFirst();
            
            
            TextFields.bindAutoCompletion(GestionProduitCategorie, new CategorieDB().getListCategorie());
            
            
            TabColReference.setCellValueFactory(new PropertyValueFactory<Produit, String>("reference"));
            TabColDesignaton.setCellValueFactory(new PropertyValueFactory<Produit, String>("designation"));
            TabColMarque.setCellValueFactory(new PropertyValueFactory<Produit, String>("marque"));
            TabColCategorie.setCellValueFactory(new PropertyValueFactory<Produit, String>("categorie"));
            
            TabColPrixAchatTTC.setCellValueFactory(new PropertyValueFactory<Produit, String>("prixachatttc"));
            TabColPrixAchatTTC.setStyle( "-fx-alignment: CENTER;");
            TabColPrixAchatTTC.getStyleClass().add("Center");
        
            TabColPrixVenteTTC.setCellValueFactory(new PropertyValueFactory<Produit, String>("prixventettc"));
            TabColPrixVenteTTC.setStyle( "-fx-alignment: CENTER;");
            TabColPrixVenteTTC.getStyleClass().add("Center");
            
            if(TypePrixTTC){
                TabColPrixVenteTTC.setVisible(true);
                TabColPrixAchatTTC.setVisible(false);
            }else{
                TabColPrixAchatTTC.setVisible(true);
                TabColPrixVenteTTC.setVisible(false);
            }
            

            TabColQuantite.setCellValueFactory(new PropertyValueFactory<Produit, String>("quantite"));
            TabColQuantite.setStyle( "-fx-alignment: CENTER;");
            TabColQuantite.getStyleClass().add("Center");

            TabColAction.setStyle( "-fx-alignment: CENTER;");
            TabColAction.getStyleClass().add("Center");
            
            if(TypePrixTTC){//Vente Stock peux être négatif table produit
                if(User.SotckNegatif){ //L'utilisateur à le droit de vente en négative
                    PaneStockNegaNon.setVisible(true);
                    TextEnStock.setVisible(true);
                }
            }else{ //Achat table produit
                PaneStockNegaNon.setVisible(true);
                TextEnStock.setVisible(true);
            }

            //table stock
            StockNegaOui.setOnMouseClicked(new EventHandler<MouseEvent>() {
                public void handle(MouseEvent me) {
                    StockNegatif = false;
                    SearchProduit();
                }
            });

            //table produit
            StockNegaNon.setOnMouseClicked(new EventHandler<MouseEvent>() {
                public void handle(MouseEvent me) {
                    StockNegatif = true;
                    SearchProduit();
                }
            });
            
            
        ButtonSearchProduit.setOnMouseClicked(new EventHandler<MouseEvent>() {
            public void handle(MouseEvent me) {
                SearchProduit();
            }
        });
        
        anchorpane.setOnKeyPressed(new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent ke) {
                if (ke.getCode().equals(KeyCode.ENTER)) {
                    SearchProduit();
                }
            }
        });
        
        GestionSearchProduit();
        
        } catch (IOException ex) {
            logger.error("RechercherProduitController  : RechercherProduit.fxml :" + ex.getMessage());
        }
    }
    
    
    public void Show()
    {
        StackPane Sp = new StackPane();
            
        Scene scene = new Scene(Sp);
        
        Sp.setPrefSize((double)MyWindow.PrincipalContentWidth, (double)MyWindow.PrincipalContentHeight);
       
        Stage stage = MyWindow.myStage;
       
        Sp.getChildren().add(MyWindow.myParent);
        Sp.getChildren().add(nodeFxml);
            
        stage.setScene(scene);
        stage.show();
    }
    
    //Define the button cell
    private class ButtonCell extends TableCell<Produit, Boolean> {
        
        final Button cellButton = new Button();
        
        ButtonCell(){
            
        cellButton.getStyleClass().add("btn-icon-primary");
        Image coffeeImage = new Image(getClass().getResourceAsStream("/Public/icon/iconaffecter.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) {
                try {
                    // get Selected ItemButtonCell
                    Produit currentPerson = (Produit) ButtonCell.this.getTableView().getItems().get(ButtonCell.this.getIndex());
                    
                    FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/Views/Devis/DevisAjouter.fxml"));
                    Parent devis = (Parent) fxmlLoader.load();
                    
                    DevisAjouterController devisajouter = fxmlLoader.getController();
                    devisajouter.SetProduit(currentPerson.getReference());
                    
                    MyWindow mywindows = new MyWindow();
                    mywindows.Refresh(devis, 3);
                } catch (IOException ex) {
                    logger.error("RechercherProduitController  : ButtonCell :" + 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);
            }
        }
        
        
        
    }
    
    
    @FXML
    private void QuiterButtonAction(ActionEvent event) throws IOException {
        anchorpane.setVisible(false);
    }
    
    
          
/******************************************************************************                                                                             *
 *                                                                              *
 *                       Methode last Next TableView                            *
 * *                                                                            *
 ******************************************************************************/  
 
    private void SearchProduit()
    {
        ProgressBarProduit.setVisible(true);
        
        ButtonSearchProduit.setDisable(true);
        
        ThreadSearchRerchecheProduit = new Service<Void>(){
            @Override
            protected Task<Void> createTask(){
                return new Task<Void>(){
                    @Override
                    protected Void call() throws Exception{
                        
                        position = 0;
                        
                        actuellepage = 1;
                        
                        ObservableList<Produit> ListeCltPersonne = new ProduitDB().SearchProduit(
                                                                                        position, 
                                                                                        nbrligne, 
                                                                                        StockNegatif, 
                                                                                        GestionProduitReference.getText(),  
                                                                                        GestionProduitCategorie.getText(), 
                                                                                        GestionProduitMarque.getText(),
                                                                                        GestionProduitDesignation.getText());
                        
                        TableViewListeGestionProduit.setItems(null);
                        TableViewListeGestionProduit.refresh();
                        TableViewListeGestionProduit.setItems(ListeCltPersonne);
                        
                        totalcount = new ProduitDB().nbrSearchProduit(StockNegatif, GestionProduitReference.getText(), GestionProduitCategorie.getText(), GestionProduitMarque.getText(), GestionProduitDesignation.getText());
                        
                        if(totalcount > 0){
                            ActuellePage.setText("1");
                        }else{
                            ActuellePage.setText("0");
                        }
                        
                        if(totalcount % nbrligne==0){ 
                            nbrpage = totalcount / nbrligne ;
                        }
                        else{ 
                            nbrpage = (totalcount / nbrligne) + 1 ; 
                        }
                        NbrPage.setText(Integer.toString(nbrpage));
                        
                        return null;
                    }
                };
            }
	};
        
        ThreadSearchRerchecheProduit.setOnSucceeded(new EventHandler<WorkerStateEvent>(){
            @Override
            public void handle(WorkerStateEvent event){
                ProgressBarProduit.setVisible(false);
                ButtonSearchProduit.setDisable(false);
                LabelCount.setText(totalcount.toString());
                
            }
        });
        ThreadSearchRerchecheProduit.start();
    }
    
    
    
    private void NextLastSearchProduit(Integer ParmPosition, Integer ParamNbrligne)
    {
        ProgressBarProduit.setVisible(true);
        
        ButtonSearchProduit.setDisable(true);
        
        ThreadSearchRerchecheProduit = new Service<Void>(){
            @Override
            protected Task<Void> createTask(){
                return new Task<Void>(){
                    @Override
                    protected Void call() throws Exception{
                        
                        ObservableList<Produit> ListeCltPersonne = new ProduitDB().SearchProduit(
                                                                                        ParmPosition, 
                                                                                        ParamNbrligne, 
                                                                                        StockNegatif, 
                                                                                        GestionProduitReference.getText(),  
                                                                                        GestionProduitCategorie.getText(), 
                                                                                        GestionProduitMarque.getText(),
                                                                                        GestionProduitDesignation.getText());
                            
                        TableViewListeGestionProduit.setItems(ListeCltPersonne);
                        
                        return null;
                    }
                };
            }
	};
        
        ThreadSearchRerchecheProduit.setOnSucceeded(new EventHandler<WorkerStateEvent>(){
            @Override
            public void handle(WorkerStateEvent event){
                ProgressBarProduit.setVisible(false);
                ButtonSearchProduit.setDisable(false);
            }
        });
        ThreadSearchRerchecheProduit.start();
    }
  
    private void GestionSearchProduit()
    {
        NbrLigne.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener<Number>() {

            public void changed(ObservableValue ov,  Number value, Number new_value) {
                nbrligne= Integer.parseInt((String) cursors.get(new_value.intValue()));
                if(totalcount % nbrligne==0){ nbrpage = totalcount / nbrligne ;}
                else{ nbrpage = (totalcount / nbrligne) + 1 ; }
                NbrPage.setText(Integer.toString(nbrpage));
                position=0;
                ActuellePage.setText("1");
                actuellepage=1;
                NextLastSearchProduit(position, nbrligne);
            }
        });

        if(totalcount % nbrligne==0){ nbrpage = totalcount / nbrligne ;}
        else{ nbrpage = (totalcount / nbrligne) + 1 ; }
        NbrPage.setText(Integer.toString(nbrpage));


        //next page
        nextgroupe.setOnMousePressed(new EventHandler<MouseEvent>(){
            @Override
            public void handle(MouseEvent event) {
                if(actuellepage<nbrpage)
                {
                    position=position+nbrligne;
                    NextLastSearchProduit(position, nbrligne);
                    actuellepage=actuellepage+1 ;
                    ActuellePage.setText(Integer.toString(actuellepage));

                }
            }
        }); 

        //last page
        lastgroupe.setOnMousePressed(new EventHandler<MouseEvent>(){
            @Override
            public void handle(MouseEvent event) {
                if(actuellepage>1)
                {
                    position=position-nbrligne;
                    NextLastSearchProduit(position, nbrligne);
                    actuellepage=actuellepage-1 ;
                    ActuellePage.setText(Integer.toString(actuellepage));
                }
            }
        }); 

        //next page avec pas de 5
        avancergroupe.setOnMousePressed(new EventHandler<MouseEvent>(){
            @Override
            public void handle(MouseEvent event) {
                if(actuellepage+3<nbrpage)
                {
                    position=(position+4)+nbrligne;
                    NextLastSearchProduit(position, nbrligne);
                    actuellepage=actuellepage+3 ;
                    ActuellePage.setText(Integer.toString(actuellepage));

                }
            }
        });

        //last page avec un pas de -5
        retourgroupe.setOnMousePressed(new EventHandler<MouseEvent>(){
            @Override
            public void handle(MouseEvent event) {
                if(actuellepage-3>1){
                    position=(position-4)-nbrligne;
                    NextLastSearchProduit(position, nbrligne);
                    actuellepage=actuellepage-3 ;
                    ActuellePage.setText(Integer.toString(actuellepage));
                }
            }
        });

    }
    
}
