
package Controllers.Stock;

import Controllers.Dialog.MessageControle;
import Controllers.Dialog.ShowDialog;
import Controllers.Traitement.Adaptateur;
import Controllers.Traitement.ParametreSystem;
import Models.Categorie.CategorieDB;
import Models.Stock.BonSortie;
import Models.Stock.BondeSortieDB;
import Models.Stock.StockDB;
import javafx.scene.control.ProgressBar;
import java.io.IOException;
import java.net.URL;
import java.time.LocalDate;
import java.util.ResourceBundle;

import org.apache.log4j.Logger;
import javafx.beans.property.SimpleBooleanProperty;
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.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.DatePicker;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.ToggleButton;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
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.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.util.Callback;
import org.controlsfx.control.textfield.TextFields;

/**
 * FXML Controller class
 * @author Maher Ben Tili
 */
public class BondeSortieController implements Initializable {

    Logger logger = Logger.getLogger(BondeSortieController.class.getName());
    
    @FXML private AnchorPane   AnchorPaneBonSortie;
    
    @FXML private ProgressBar ProgressBarStockBonSortie;
    
    @FXML private Text LocalEmetteur ;
   
    @FXML private ComboBox ComboLocale;
    @FXML private ToggleButton Activate ;    //permet d'activer la l'option de rechercher dans la table  produit (Stock négative)
    @FXML private DatePicker DateBS;
    @FXML private TextField TextFieldCategorie;
    @FXML private TextField SortieTransporteur;
    @FXML private TextField ReferenceBE;
    @FXML private TextField DesignatonBE;
    @FXML private TextField MarqueBE;
    
    @FXML private TableView<ListProduitRech> TableViewListeProduitRechercher ;
    @FXML private TableColumn<ListProduitRech ,String> TabColRechReference;
    @FXML private TableColumn<ListProduitRech ,String> TabColRechDesignaton;
    @FXML private TableColumn<ListProduitRech ,String> TabColRechMarque ;
    @FXML private TableColumn<ListProduitRech ,String> TabColRechCategorie;
    @FXML private TableColumn<ListProduitRech ,String> TabColRechPrixTTC;
    @FXML private TableColumn<ListProduitRech ,String> TabColRechTVA;
    @FXML private TableColumn<ListProduitRech ,String> TabColRechQuantite;
    @FXML private TableColumn<ListProduitRech, Boolean> TabColRechAddAction ;
    
    
    @FXML private TableView<ListProduitBon> TableViewListeProduitBE ;
    @FXML private TableColumn<ListProduitBon ,String> TabColBEReference;
    @FXML private TableColumn<ListProduitBon ,String> TabColBEDesignaton;
    @FXML private TableColumn<ListProduitBon ,String> TabColBEMarque ;
    @FXML private TableColumn<ListProduitBon ,String> TabColBECategorie;
    @FXML private TableColumn<ListProduitBon ,String> TabColBEPrixTTC;
    @FXML private TableColumn<ListProduitBon ,String> TabColBEQuantiteTTC;
    @FXML private TableColumn<ListProduitBon ,String> TabColBETVA;
    @FXML private TableColumn<ListProduitBon, Boolean> TabColBEAddAction ;
    
    private Service<Void> ThreadSearchCategorieSortie;
    
    ObservableList<ListProduitBon> data=FXCollections.observableArrayList();
    BondeSortieDB bonsortiedb = new BondeSortieDB();
    StockDB stockdb = new StockDB();
    
    Boolean StockNegative = false;  //option de ToggleGroup Activate ;
    String categorie="" ;
    String Reference="" ;
    String designaton="" ;
    String marque="" ;
    
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        
        LocalEmetteur.setText(ParametreSystem.NomLocalPC);
        
        DateBS.setValue(LocalDate.now());
        
       
        
        
        Activate.setOnMouseClicked(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent t) {
                StockNegative = Activate.selectedProperty().getValue();
            }
        });
        
        
        //Liste des Locales
        ComboLocale.setOnMouseClicked(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent t) {
                ComboLocale.setStyle("-fx-border-color:#cfcfcf;");
                ComboLocale.getItems().clear();
                ComboLocale.getItems().addAll(stockdb.getListLocal());
            }
        }); 
        
        
        
        TableViewListeProduitBE.setEditable(true);
        
        //Pour la premiére table View rechercher un produit 
        TabColRechReference.setCellValueFactory(new PropertyValueFactory<ListProduitRech, String>("reference"));
        TabColRechDesignaton.setCellValueFactory(new PropertyValueFactory<ListProduitRech, String>("designaton"));
        TabColRechMarque.setCellValueFactory(new PropertyValueFactory<ListProduitRech, String>("marque"));
        TabColRechCategorie.setCellValueFactory(new PropertyValueFactory<ListProduitRech, String>("categorie"));
        TabColRechPrixTTC.setCellValueFactory(new PropertyValueFactory<ListProduitRech, String>("prixttc"));
        TabColRechPrixTTC.setStyle( "-fx-alignment: CENTER_RIGHT; -fx-font-weight:bold;");
        TabColRechTVA.setCellValueFactory(new PropertyValueFactory<ListProduitRech, String>("TVA"));
        TabColRechTVA.setStyle( "-fx-alignment: CENTER; -fx-font-weight:bold;");
        TabColRechQuantite.setCellValueFactory(new PropertyValueFactory<ListProduitRech, String>("quantite"));
        TabColRechQuantite.setStyle( "-fx-alignment: CENTER; -fx-font-weight:bold;");
        TabColRechAddAction.setSortable(true);
        TabColRechAddAction.setStyle( "-fx-alignment: CENTER;");
        
        TabColRechAddAction.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<ListProduitRech, Boolean>, 
            ObservableValue<Boolean>>() {
            @Override
            public ObservableValue<Boolean> call(TableColumn.CellDataFeatures<ListProduitRech, Boolean> p) {
                return new SimpleBooleanProperty(p.getValue() != null);
            }
        });
        
        // create a cell value factory with an add button for each row in the table.
        TabColRechAddAction.setCellFactory(new Callback<TableColumn<ListProduitRech, Boolean>, TableCell<ListProduitRech, Boolean>>() {
          @Override 
          public TableCell<ListProduitRech, Boolean> call(TableColumn<ListProduitRech, Boolean> personBooleanTableColumn) {
            return new BondeSortieController.ButtonCell();
          }
        });
        
        
        //Pour la deuxèmé table View rechercher un produit 
        TabColBEReference.setCellValueFactory(new PropertyValueFactory<ListProduitBon, String>("reference"));
        TabColBEDesignaton.setCellValueFactory(new PropertyValueFactory<ListProduitBon, String>("designaton"));
        TabColBEMarque.setCellValueFactory(new PropertyValueFactory<ListProduitBon, String>("marque"));
        TabColBECategorie.setCellValueFactory(new PropertyValueFactory<ListProduitBon, String>("categorie"));
        TabColBEPrixTTC.setCellValueFactory(new PropertyValueFactory<ListProduitBon, String>("prixttc"));
        TabColBEPrixTTC.setStyle( "-fx-alignment: CENTER_RIGHT; -fx-font-weight:bold; -fx-font-size: 9pt;");
        TabColBETVA.setCellValueFactory(new PropertyValueFactory<ListProduitBon, String>("tva"));
        TabColBETVA.setStyle( "-fx-alignment: CENTER; -fx-font-weight:bold; -fx-font-size: 10pt;");
        TabColBEQuantiteTTC.setCellValueFactory(new PropertyValueFactory<ListProduitBon, String>("quantite"));
        TabColBEQuantiteTTC.setStyle( "-fx-alignment: CENTER; -fx-font-weight:bold; -fx-font-size: 10pt;");
        //Ajouter l'option textfield
        TabColBEQuantiteTTC.setCellFactory(TextFieldTableCell.<ListProduitBon>forTableColumn());
        
        
        //Valier l'opertion de modification de la quantite par la sourie 
        TabColBEQuantiteTTC.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<ListProduitBon, String>>() {
        @Override
        public void handle(TableColumn.CellEditEvent<ListProduitBon, String> t) {
            
            String NewQuantite = t.getNewValue();
            String OldQuantite = t.getOldValue();
           
            try{
                double d = Double.parseDouble(NewQuantite);
                String ref =t.getTableView().getItems().get(t.getTablePosition().getRow()).getReference();
                Integer quantStock =  bonsortiedb.GetQuantiteStock(ref);
                //le cas ou il tape un zéro 0
                if(d<=0){
                    ((ListProduitBon) t.getTableView().getItems().get(t.getTablePosition().getRow())).setQuantite(OldQuantite);
                }
                // le ca ou la quantité BS ne doit pas dépassé la quantité en stock
                else if(!StockNegative && quantStock<d){
                    final MessageControle messagecontrol = new MessageControle();
                    Text text3 = new Text();
                    text3.setText("La quantité en bon de sortie ne doit pas dépassé la quantité en stock");
                    text3.setFont(Font.font("Arial", FontWeight.BOLD, 13));
                    text3.setFill(Color.web("#363a38"));
                    messagecontrol.DetailMSG.getChildren().add(text3);

                    messagecontrol.bouttonOK.setOnAction(new EventHandler<ActionEvent>() {
                        @Override
                        public void handle(ActionEvent event) {
                            messagecontrol.stackpane.setVisible(false);
                        }
                    });
                    messagecontrol.ShowNotification();
                }
                else{
                    ((ListProduitBon) t.getTableView().getItems().get(t.getTablePosition().getRow())).setQuantite(NewQuantite);
                }
                
                
                
            }
            //le cas ou la nouvelle quantité n'est pas un entier
            catch(NumberFormatException nfe){
               //inséré l'ancienne valeur de quantité
               ((ListProduitBon) t.getTableView().getItems().get(t.getTablePosition().getRow())).setQuantite(OldQuantite);
            }
            //actualiser la ligne
            TableViewListeProduitBE.getColumns().get(t.getTablePosition().getRow()).setVisible(false);
            TableViewListeProduitBE.getColumns().get(t.getTablePosition().getRow()).setVisible(true);
        }
        
        });
        
        final TextField TextQuantiteTTC = new TextField();
        TextQuantiteTTC.setPromptText("quantite");
        TextQuantiteTTC.setMaxWidth(TabColBEQuantiteTTC.getPrefWidth());
       
        
        TabColBEAddAction.setSortable(true);
        TabColBEAddAction.setStyle( "-fx-alignment: CENTER;");
        TabColBEAddAction.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<ListProduitBon, Boolean>, 
            ObservableValue<Boolean>>() {
            @Override
            public ObservableValue<Boolean> call(TableColumn.CellDataFeatures<ListProduitBon, Boolean> p) {
                return new SimpleBooleanProperty(p.getValue() != null);
            }
        });
 
        // create a cell value factory with an add button for each row in the table.
        TabColBEAddAction.setCellFactory(new Callback<TableColumn<ListProduitBon, Boolean>, TableCell<ListProduitBon, Boolean>>() {
          @Override 
          public TableCell<ListProduitBon, Boolean> call(TableColumn<ListProduitBon, Boolean> personBooleanTableColumn) {
            return new BondeSortieController.ButtonCellBE();
          }
        });
        
        
        //get recheche produit
        this.KeyEventProduit();
        
        this.setCategorie();
    }    
    
    
    
    //Methode pour récupéré la selection du catégorie
    private void setCategorie()
    {
        ProgressBarStockBonSortie.setVisible(true);
        
        ThreadSearchCategorieSortie = new Service<Void>(){
            @Override
            protected Task<Void> createTask(){
                return new Task<Void>(){
                    @Override
                    protected Void call() throws Exception{
                        
                        TextFields.bindAutoCompletion(TextFieldCategorie, new CategorieDB().getListCategorie());
                        
                        return null;
                    }
                };
            }
	};
        
        ThreadSearchCategorieSortie.setOnSucceeded(new EventHandler<WorkerStateEvent>(){
            @Override
            public void handle(WorkerStateEvent event){
                ProgressBarStockBonSortie.setVisible(false);
            }
        });
        ThreadSearchCategorieSortie.start();
    }
    
    //Define the button cell
    private class ButtonCell extends TableCell<ListProduitRech, 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) {
                    
                    ListProduitRech ListProRech = (ListProduitRech) ButtonCell.this.getTableView().getItems().get(ButtonCell.this.getIndex());
                    
                    ListProduitBon listbrodbe = new ListProduitBon(ListProRech.getReference(), ListProRech.getDesignaton(), ListProRech.getMarque(), ListProRech.getCategorie(), ListProRech.getPrixttc(), "1", ListProRech.getTVA());
                    
                    //lorce qu'il y a plus que ligne
                    if(data.size()>0){
                       boolean result = false ;
                       int indise = 1;
                       //Verifier si la produit exsiste déja
                       while(indise<=data.size() && !result){
                           result =  data.get(indise-1).getReference().equals(ListProRech.getReference());
                           //si il le produit exisite déja on ajoute 1 a la quantité 
                           if(result){
                               
                               //quantité disponible en stock
                               Integer QuantiteStock = Integer.valueOf(ListProRech.getQuantite());
                               
                               Integer quantiteBS=Integer.parseInt(data.get(indise-1).getQuantite())+1;
                               
                               //le cas ou quantité en bon de sortie ne doit pas dépassé la quantité en stock
                               if(!StockNegative){
                                    if(quantiteBS<=QuantiteStock){
                                        data.get(indise-1).setQuantite(Integer.toString(quantiteBS));
                                    }
                                     else{
                                         //le ca ou la quantité en bon de sortie dépasse la quntité en stock
                                         final MessageControle messagecontrol = new MessageControle();

                                         Text text3 = new Text();
                                         text3.setText("La quantité en bon de sortie ne doit pas dépassé la quantité en stock");
                                         text3.setFont(Font.font("Arial", FontWeight.BOLD, 13));
                                         text3.setFill(Color.web("#363a38"));
                                         messagecontrol.DetailMSG.getChildren().add(text3);

                                         messagecontrol.bouttonOK.setOnAction(new EventHandler<ActionEvent>() {
                                             @Override
                                             public void handle(ActionEvent event) {
                                                 messagecontrol.stackpane.setVisible(false);
                                             }
                                         });
                                        messagecontrol.ShowNotification();
                                    }
                                }
                                // le ca ou on la la possibilité de stock négative
                                else{
                                   data.get(indise-1).setQuantite(Integer.toString(quantiteBS));
                               }
                                TableViewListeProduitBE.getColumns().get(indise-1).setVisible(false);
                                TableViewListeProduitBE.getColumns().get(indise-1).setVisible(true);
                           }
                           indise++; 
                       }
                       //si le produit n'exsiste pas on la joute à la table view
                       if(!result){
                            data.add(listbrodbe); 
                        }
                    }
                    else{
                         data.add(listbrodbe);
                    }
                   TableViewListeProduitBE.setItems(data);
                }
            });
        }

        //Display button if the row is not empty
        @Override
        protected void updateItem(Boolean t, boolean empty) {
            if(!empty){
                setGraphic(cellButton);
            } else {
                setGraphic(null);
            }
        }
    }
    
    //methode pour céer la bon de sortie
    @FXML
    private void CreerBonSortieButtonAction(ActionEvent event) throws IOException {
        
        if(ComboLocale.getValue()==null){
            ComboLocale.setStyle("-fx-border-color:#f20606;");
            
        }
        
        else if(data.isEmpty()){
            ComboLocale.setStyle("-fx-border-color:#cfcfcf;");
            final MessageControle messagecontrol = new MessageControle();

            Text text3 = new Text();
            text3.setText("Vous devez ajouter au moin un produit à la liste des produits (Sortie)");
            text3.setFont(Font.font("Arial", FontWeight.BOLD, 13));
            text3.setFill(Color.web("#363a38"));
            messagecontrol.DetailMSG.getChildren().add(text3);

            messagecontrol.bouttonOK.setOnAction(new EventHandler<ActionEvent>() {
                @Override
                public void handle(ActionEvent event) {
                    messagecontrol.stackpane.setVisible(false);
                }
            });

            messagecontrol.ShowNotification();
            
        }
        else{
            final BondeSortieDialogConfirmation notification = new BondeSortieDialogConfirmation();
            
            notification.Date.setText(Adaptateur.NormalDateFormat(DateBS.getValue()));
            notification.Tranporteur.setText(SortieTransporteur.getText());
            notification.Affecter.setText(ComboLocale.getValue().toString());
            notification.Confdata= data;
            notification.bouttonOK.setOnAction(new EventHandler<ActionEvent>() {
                @Override
                public void handle(ActionEvent event) {
                    
                    //date bon de sortie
                    BonSortie bonsortie = new BonSortie();
                    bonsortie.setDate(DateBS.getValue().toString());
                    bonsortie.setTransporteur(SortieTransporteur.getText());
                    bonsortie.setLocal_emetteur(ParametreSystem.NomLocalPC);
                    bonsortie.setLocal_recepteur(ComboLocale.getValue().toString());
                    bonsortie.setListe_prod(data);
                    
                    if(bonsortiedb.addBonSortie(bonsortie)){
                        
                        notification.stackpane.setVisible(false);
                        AnchorPaneBonSortie.getChildren().clear();
                        try {
                            FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/Views/Stock/BondeSortieDetail.fxml"));
                            Parent root = (Parent)fxmlLoader.load();
                            AnchorPaneBonSortie.getChildren().add(root);
                        } catch (IOException ex) {
                            logger.error("BondeSortieController  : CreerBonSortieButtonAction :" + ex.getMessage());
                        }
                    }
                    else{
                        ShowDialog SD = new ShowDialog();
                        ShowDialog.titre="Erreur Système";
                        ShowDialog.detail="Models/Stock/BonSortieController.java";
                        SD.ShowAletDialog();
                    }
                 
                }
            });
            
            notification.ShowDialg();
        }
    }
    
    
    
    //Define the button cell
    private class ButtonCellBE extends TableCell<ListProduitBon, Boolean> {
        
        final Button cellButton = new Button();
        
        ButtonCellBE(){
            cellButton.getStyleClass().add("btn-danger");
            Image coffeeImage = new Image(getClass().getResourceAsStream("/Public/icon/icondelete.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) {
                    int selectdIndex = getTableRow().getIndex();
                    data.remove(selectdIndex);
                    
                }
            });
        }

        //Display button if the row is not empty
        @Override
        protected void updateItem(Boolean t, boolean empty) {
            if(!empty){
                setGraphic(cellButton);
            } else {
                setGraphic(null);
            }
        }
    }
    
    
    private void SearchProduit()
    {
        ProgressBarStockBonSortie.setVisible(true);
        
        ThreadSearchCategorieSortie = new Service<Void>(){
            @Override
            protected Task<Void> createTask(){
                return new Task<Void>(){
                    @Override
                    protected Void call() throws Exception{
                        
                        TableViewListeProduitRechercher.setItems(bonsortiedb.getdataProdBS(Reference,designaton,marque,categorie,StockNegative));
                        
                        return null;
                    }
                };
            }
	};
        
        ThreadSearchCategorieSortie.setOnSucceeded(new EventHandler<WorkerStateEvent>(){
            @Override
            public void handle(WorkerStateEvent event){
                ProgressBarStockBonSortie.setVisible(false);
            }
        });
        ThreadSearchCategorieSortie.start();
    }
    
    private void KeyEventProduit(){
        
        ReferenceBE.setOnKeyReleased(new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent ke) {
                Reference=ReferenceBE.getText();
                designaton=DesignatonBE.getText();
                marque=MarqueBE.getText();
                if(Reference.isEmpty() && designaton.isEmpty() && marque.isEmpty()){
                    TableViewListeProduitRechercher.setItems(null);
                }
                else{
                    if (ke.getCode().equals(KeyCode.ENTER)) {
                        SearchProduit();
                    }
                }
                
            }
        });
        
        DesignatonBE.setOnKeyReleased(new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent ke) {
                Reference=ReferenceBE.getText();
                designaton=DesignatonBE.getText();
                marque=MarqueBE.getText();
                if(Reference.isEmpty() && designaton.isEmpty() && marque.isEmpty()){
                    TableViewListeProduitRechercher.setItems(null);
                }
                else{
                    if (ke.getCode().equals(KeyCode.ENTER)) {
                        SearchProduit();
                    }
                }
                
            }
        });
        
        MarqueBE.setOnKeyReleased(new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent ke) {
                Reference=ReferenceBE.getText();
                designaton=DesignatonBE.getText();
                marque=MarqueBE.getText();
                if(Reference.isEmpty() && designaton.isEmpty() && marque.isEmpty()){
                    TableViewListeProduitRechercher.setItems(null);
                }
                else{
                    if (ke.getCode().equals(KeyCode.ENTER)) {
                        SearchProduit();
                    }
                }
                
            }
        });
        
        TextFieldCategorie.setOnKeyReleased(new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent ke) {
                if (ke.getCode().equals(KeyCode.ENTER)) {
                    Reference=ReferenceBE.getText();
                    designaton=DesignatonBE.getText();
                    marque=MarqueBE.getText();
                    categorie = TextFieldCategorie.getText();
                    if (ke.getCode().equals(KeyCode.ENTER)) {
                        SearchProduit();
                    }
                }
            }
        });
        
    }
    
}
