package Controllers.Caisse;

import Controllers.Traitement.Adaptateur;
import Controllers.Traitement.ParametreSystem;
import Controllers.Traitement.contro;
import Models.Caisse.CaisseDB;
import Models.Caisse.CaisseSortieListe;
import com.gluonhq.charm.glisten.control.ProgressBar;
import java.io.IOException;
import java.net.URL;
import java.time.LocalDate;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
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.PageLayout;
import javafx.print.PageOrientation;
import javafx.print.PageRange;
import javafx.print.Paper;
import javafx.print.Printer;
import javafx.print.PrinterJob;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.DatePicker;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.AnchorPane;
import javafx.scene.text.Text;

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

    @FXML private AnchorPane  AnchorPaneCaisseClt;
    
    @FXML private DatePicker DatePickerDebut;
    @FXML private DatePicker DatePickerFin;
    
    @FXML private Text TotalSortie;
    
    @FXML private CheckBox CheckBoxChequeClt;
    @FXML private CheckBox CheckBoxEspace;
    @FXML private CheckBox CheckBoxCarteBancaire;
    
    @FXML private CheckBox  CheckBoxAchatFrs;
    @FXML private CheckBox  CheckBoxFraisFrs;
    @FXML private CheckBox  CheckBoxTraiteFrs;
    @FXML private CheckBox  CheckBoxAvoirV;
    
    @FXML private Button ButtonSortie;
    @FXML private Button ButtonPrintCaisseSortie;
    
    @FXML private ProgressBar ProgressBarCaisseSortieFrs;
    @FXML private TableView<CaisseSortieListe> TableViewCaisseFrsSortie ;
    
    @FXML private TableColumn<CaisseSortieListe ,String> TabColIdCaisseFrs;
    @FXML private TableColumn<CaisseSortieListe ,String> TabColTypeFrs;
    @FXML private TableColumn<CaisseSortieListe ,String> TabColDateFrs;
    @FXML private TableColumn<CaisseSortieListe ,String> TabColMontantFrs;
    
    @FXML private TableColumn<CaisseSortieListe ,String> TabColEspeceFrs;
    @FXML private TableColumn<CaisseSortieListe ,String> TabColChequeFrs;
    @FXML private TableColumn<CaisseSortieListe ,String> TabColCarteBancaireFrs;
    
    private Service<Void> ThreadCaisseSortie;
    
    CaisseDB CaisseDB= new CaisseDB();
    
    ObservableList<CaisseSortieListe> ObsListCaisseFrsSortie;
    ObservableList<CaisseSortieListe> TempoObsListCaisseFrsSortie;
    
    private String DateDebut ;
    private String DateFin;
    
    contro clt = new  contro();
    
    @Override
    public void initialize(URL url, ResourceBundle rb) {
       
        DatePickerDebut.setValue(LocalDate.now());
        DatePickerFin.setValue(LocalDate.now());
        
        DateDebut = DatePickerDebut.getValue().toString();
        DateFin = DatePickerFin.getValue().toString();
        
        
        TabColIdCaisseFrs.setStyle( "-fx-alignment: CENTER;");TabColIdCaisseFrs.getStyleClass().add("Center");
        TabColIdCaisseFrs.setCellValueFactory(new PropertyValueFactory<CaisseSortieListe, String>("IdCaisseClt"));
        
        TabColTypeFrs.setStyle( "-fx-alignment: CENTER;");TabColTypeFrs.getStyleClass().add("Center");
        TabColTypeFrs.setCellValueFactory(new PropertyValueFactory<CaisseSortieListe, String>("Type"));
        
        TabColDateFrs.setStyle( "-fx-alignment: CENTER;");TabColDateFrs.getStyleClass().add("Center");
        TabColDateFrs.setCellValueFactory(new PropertyValueFactory<CaisseSortieListe, String>("Date"));
        
        TabColMontantFrs.setStyle( "-fx-alignment: CENTER;");TabColMontantFrs.getStyleClass().add("Center");
        TabColMontantFrs.setCellValueFactory(new PropertyValueFactory<CaisseSortieListe, String>("Montant"));
        
        TabColEspeceFrs.setStyle( "-fx-alignment: CENTER;");TabColEspeceFrs.getStyleClass().add("Center");
        TabColEspeceFrs.setCellValueFactory(new PropertyValueFactory<CaisseSortieListe, String>("Espece"));
        
        TabColChequeFrs.setStyle( "-fx-alignment: CENTER;");TabColChequeFrs.getStyleClass().add("Center");
        TabColChequeFrs.setCellValueFactory(new PropertyValueFactory<CaisseSortieListe, String>("Cheque"));
        
        TabColCarteBancaireFrs.setStyle( "-fx-alignment: CENTER;");TabColCarteBancaireFrs.getStyleClass().add("Center");
        TabColCarteBancaireFrs.setCellValueFactory(new PropertyValueFactory<CaisseSortieListe, String>("CarteBancaire"));
        
        ButtonSortie.setOnAction(new EventHandler<ActionEvent>() {
            @Override 
            public void handle(ActionEvent actionEvent) {
            try{ 
                DateDebut = DatePickerDebut.getConverter().fromString(DatePickerDebut.getEditor().getText()).toString();
                DateFin = DatePickerFin.getConverter().fromString(DatePickerFin.getEditor().getText()).toString();
                getCaisseSortieThread();
            }catch(Exception ex){}
            
            }
        });
       
        this.FiltreCaisse();
        
        this.CaisseSortiePrintButton();
        
    }    
    
    private void FiltreCaisse(){
        CheckBoxChequeClt.setOnAction(new EventHandler<ActionEvent>(){
            @Override
            public void handle(ActionEvent t) {
                getDetailSortieCheck();
            }
        });
        CheckBoxEspace.setOnAction(new EventHandler<ActionEvent>(){
           @Override
           public void handle(ActionEvent t) {
               getDetailSortieCheck();
           }
        });
        CheckBoxCarteBancaire.setOnAction(new EventHandler<ActionEvent>(){
           @Override
           public void handle(ActionEvent t) {
               getDetailSortieCheck();
           }
        });
        
        CheckBoxAchatFrs.setOnAction(new EventHandler<ActionEvent>(){
           @Override
           public void handle(ActionEvent t) {
               getDetailSortieCheck();
           }
        });
        CheckBoxFraisFrs.setOnAction(new EventHandler<ActionEvent>(){
           @Override
           public void handle(ActionEvent t) {
               getDetailSortieCheck();
           }
        });
        CheckBoxTraiteFrs.setOnAction(new EventHandler<ActionEvent>(){
           @Override
           public void handle(ActionEvent t) {
               getDetailSortieCheck();
           }
        });
        
        CheckBoxAvoirV.setOnAction(new EventHandler<ActionEvent>(){
           @Override
           public void handle(ActionEvent t) {
               getDetailSortieCheck();
           }
        });
    }
    
    
    public void getCaisseSortieThread()
    {
        TotalSortie.setText("--");
        
        DatePickerDebut.setDisable(true);
        DatePickerFin.setDisable(true);
        ButtonSortie.setDisable(true);
        ButtonPrintCaisseSortie.setDisable(true);
        
        ProgressBarCaisseSortieFrs.setVisible(true);
        TableViewCaisseFrsSortie.setItems(null);
        
        CheckBoxChequeClt.setSelected(true);
        CheckBoxEspace.setSelected(true);
        CheckBoxCarteBancaire.setSelected(true);
        
        //Sortie
        CheckBoxAchatFrs.setSelected(true);
        CheckBoxFraisFrs.setSelected(true);
        
        ThreadCaisseSortie = new Service<Void>(){
            @Override
            protected Task<Void> createTask(){
                return new Task<Void>(){
                    @Override
                    protected Void call() throws Exception{
                        
                        /*******************Sortie**********************/
                        ObsListCaisseFrsSortie = CaisseDB.GetDataCaisseFrsSortie(DateDebut, DateFin);
                        System.out.println(ObsListCaisseFrsSortie.size());
                        TempoObsListCaisseFrsSortie = ObsListCaisseFrsSortie;
                        
                        int indiceSortie = 0;
                        float FloatTotalSortie = 0;
                        while(indiceSortie<ObsListCaisseFrsSortie.size()){
                            FloatTotalSortie += ObsListCaisseFrsSortie.get(indiceSortie).getFloatMontant();
                            indiceSortie++;
                        }
                        
                        TotalSortie.setText(Adaptateur.FloatToStringEspaceCurrency(FloatTotalSortie));
                        
                        TableViewCaisseFrsSortie.setItems(ObsListCaisseFrsSortie);
                        
                        return null;
                    }
                };
            }
	};
        
        ThreadCaisseSortie.setOnSucceeded(new EventHandler<WorkerStateEvent>(){
            @Override
            public void handle(WorkerStateEvent event){
                ProgressBarCaisseSortieFrs.setVisible(false);
                DatePickerDebut.setDisable(false);
                DatePickerFin.setDisable(false);
                ButtonPrintCaisseSortie.setDisable(false);
                ButtonSortie.setDisable(false);
            }
        });
        ThreadCaisseSortie.start();
    }
    
    
    
    
    
    
    public void getDetailSortieCheck(){
        
        TempoObsListCaisseFrsSortie = FXCollections.observableArrayList();
                
        boolean CheckCheque = CheckBoxChequeClt.isSelected();
        boolean CheckEspace = CheckBoxEspace.isSelected();
        boolean CheckCarteBancaire= CheckBoxCarteBancaire.isSelected();
        
        boolean CheckFrais = CheckBoxFraisFrs.isSelected();
        boolean CheckAchat = CheckBoxAchatFrs.isSelected();
        boolean CheckTraite = CheckBoxTraiteFrs.isSelected();
        boolean CheckAvoirV = CheckBoxAvoirV.isSelected();
        
        float FloatTotalSortie = 0;
        
        // 0-Vente Comptant   |    1-Vente Facilité Avance  |   2 Vente Commande Avance | 3 traite clt |  4 ChequeClt
        if(ObsListCaisseFrsSortie.size()>0){
            int indice = 0;
            while(indice<ObsListCaisseFrsSortie.size()){
                
                CaisseSortieListe ListCaisseFrsSortie = ObsListCaisseFrsSortie.get(indice);
                
                //Achat
                if(CheckAchat && (ListCaisseFrsSortie.getType().equals("Achat")) ){
                    
                    //Paiement Espace
                    if(CheckEspace && (ListCaisseFrsSortie.getCodeType().equals("Espèce")) ){
                        FloatTotalSortie += ListCaisseFrsSortie.getFloatMontant();
                        TempoObsListCaisseFrsSortie.add(ListCaisseFrsSortie);
                    }

                    //Paiement Chèque
                    if(CheckCheque && (ListCaisseFrsSortie.getCodeType().equals("Chèque")) ){
                        FloatTotalSortie += ListCaisseFrsSortie.getFloatMontant();
                        TempoObsListCaisseFrsSortie.add(ListCaisseFrsSortie);
                    }

                    //Paiement Carte Bancaire
                    if(CheckCarteBancaire && (ListCaisseFrsSortie.getCodeType().equals("Carte Bancaire")) ){
                        FloatTotalSortie += ListCaisseFrsSortie.getFloatMontant();
                        TempoObsListCaisseFrsSortie.add(ListCaisseFrsSortie);
                    }

                    //Traite Frs
                    if(CheckTraite && (ListCaisseFrsSortie.getCodeType().equals("Traite")) ){
                        FloatTotalSortie += ListCaisseFrsSortie.getFloatMontant();
                        TempoObsListCaisseFrsSortie.add(ListCaisseFrsSortie);
                    }
                }
                
                //Frais
                if(CheckFrais && (ListCaisseFrsSortie.getType().equals("Frais")) ){
                    
                    //Paiement Espace
                    if(CheckEspace && (ListCaisseFrsSortie.getCodeType().equals("Espèce")) ){
                        FloatTotalSortie += ListCaisseFrsSortie.getFloatMontant();
                        TempoObsListCaisseFrsSortie.add(ListCaisseFrsSortie);
                    }

                    //Paiement Chèque
                    if(CheckCheque && (ListCaisseFrsSortie.getCodeType().equals("Chèque")) ){
                        FloatTotalSortie += ListCaisseFrsSortie.getFloatMontant();
                        TempoObsListCaisseFrsSortie.add(ListCaisseFrsSortie);
                    }

                    //Paiement Carte Bancaire
                    if(CheckCarteBancaire && (ListCaisseFrsSortie.getCodeType().equals("Carte Bancaire")) ){
                        FloatTotalSortie += ListCaisseFrsSortie.getFloatMontant();
                        TempoObsListCaisseFrsSortie.add(ListCaisseFrsSortie);
                    }
                }
                
                //Avoir Vente Sans Facture
                if(CheckAvoirV && (ListCaisseFrsSortie.getType().equals("Avoir VSF")) ){
                    
                    //Paiement Espace
                    if(CheckEspace && (ListCaisseFrsSortie.getCodeType().equals("Espèce")) ){
                        FloatTotalSortie += ListCaisseFrsSortie.getFloatMontant();
                        TempoObsListCaisseFrsSortie.add(ListCaisseFrsSortie);
                    }

                    //Paiement Chèque
                    if(CheckCheque && (ListCaisseFrsSortie.getCodeType().equals("Chèque")) ){
                        FloatTotalSortie += ListCaisseFrsSortie.getFloatMontant();
                        TempoObsListCaisseFrsSortie.add(ListCaisseFrsSortie);
                    }

                    //Paiement Carte Bancaire
                    if(CheckCarteBancaire && (ListCaisseFrsSortie.getCodeType().equals("Carte Bancaire")) ){
                        FloatTotalSortie += ListCaisseFrsSortie.getFloatMontant();
                        TempoObsListCaisseFrsSortie.add(ListCaisseFrsSortie);
                    }
                } 
                
                //Traite
                if(CheckTraite && (ListCaisseFrsSortie.getType().equals("Traite")) ){
                    
                    //Paiement Espace
                    if(CheckEspace && (ListCaisseFrsSortie.getCodeType().equals("Espèce")) ){
                        FloatTotalSortie += ListCaisseFrsSortie.getFloatMontant();
                        TempoObsListCaisseFrsSortie.add(ListCaisseFrsSortie);
                    }
                    
                } 
                indice++;
            }
            TableViewCaisseFrsSortie.setItems(null);
            TableViewCaisseFrsSortie.setItems(TempoObsListCaisseFrsSortie);
            TotalSortie.setText(Adaptateur.FloatToStringEspaceCurrency(FloatTotalSortie));
        }
        
    }
    
    private void CaisseSortiePrintButton()
    {
        ButtonPrintCaisseSortie.setOnAction(new EventHandler<ActionEvent>(){
           @Override
           public void handle(ActionEvent t) {
                String strPaiment = "";
                if(CheckBoxChequeClt.isSelected()){ strPaiment += "Chéque | "; }
                if(CheckBoxEspace.isSelected()){ strPaiment += "Espéce | "; }
                if(CheckBoxCarteBancaire.isSelected()){ strPaiment += "Carte Bancaire | "; }
                strPaiment = strPaiment.substring(0, strPaiment.length() - 3);

                String strType = "";
                if(CheckBoxAchatFrs.isSelected()){ strType += "Achat | "; }
                if(CheckBoxFraisFrs.isSelected()){ strType += "Frais | "; }
                if(CheckBoxTraiteFrs.isSelected()){ strType += "Traite | "; }
                if(CheckBoxAvoirV.isSelected()){ strType += "Avoir | "; }
                strType = strType.substring(0, strType.length() - 3);

                int SizelistCaisseCltSortiet = TempoObsListCaisseFrsSortie.size();
                int total = SizelistCaisseCltSortiet / 13 + 1 ;
                int page = 0;

                PrinterJob jobPrint = PrinterJob.createPrinterJob();



                jobPrint.getJobSettings().setPageRanges(new PageRange(1, total));

                if (jobPrint.showPrintDialog(null)) 
                {
                    Printer printer = jobPrint.getPrinter();
                    PageLayout pageLayout = printer.createPageLayout(Paper.A4, PageOrientation.LANDSCAPE, Printer.MarginType.DEFAULT);

                    for (int i=0; i<SizelistCaisseCltSortiet; i+=13)
                    {
                        try {
                            ObservableList<CaisseSortieListe> listTemp = FXCollections.observableArrayList();
                            
                            for (int j=i; (j<(i+13)) && (j<SizelistCaisseCltSortiet); j++)
                            {
                                CaisseSortieListe ListCaisseClt = TempoObsListCaisseFrsSortie.get(j);
                                
                                listTemp.add(ListCaisseClt);
                            }
                            FXMLLoader fxmlLoaderCaisseSortiePrint = new FXMLLoader(getClass().getResource("/Views/Caisse/CaisseSortiePrint.fxml"));
                            final Node ParentFxmlCaisseSortiePrint = (Node)fxmlLoaderCaisseSortiePrint.load();
                            CaisseSortiePrintController caisseSortiePrintController = fxmlLoaderCaisseSortiePrint.getController();
                            page++;
                            
                            caisseSortiePrintController.setCaisseSortiePrint(
                                    Adaptateur.NormalDateFormat(DateDebut)+" à "+Adaptateur.NormalDateFormat(DateFin),
                                    ParametreSystem.NomLocalPC,
                                    TotalSortie.getText(),
                                    strPaiment,
                                    page+"/"+total,
                                    strType,
                                    listTemp);
                            
                            jobPrint.printPage(pageLayout, ParentFxmlCaisseSortiePrint);
                        } catch (IOException ex) {
                            Logger.getLogger(CaisseSortieController.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                    jobPrint.endJob();
                }
           }
        });
    }
    
    
}
