package Test;

import API.Etudiant;
import API.Groupe;

// TODO: Trier ca pour faire un import par package utilises (j'ai eu la flemme de le faire)
import javax.swing.*;
import java.awt.*;

import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.TableModel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Objects;

public class Controller implements ActionListener, ListSelectionListener {
    private final BDatabase db;
    private final ProfView pv;
    private final AdminView av;
    private final ArrayList<Etudiant> e;
    private final ArrayList<Groupe> g;
    private JTable currentJTableUse;

    public Controller(ArrayList<Etudiant> e, ArrayList<Groupe> g) {
        this.e = e;
        this.g = g;
        this.db = new BDatabase();
        this.pv = new ProfView(e, g, this);
        System.out.println("[+] Demarrage de la vue professeur -> " + pv);
        this.av = new AdminView(e, g, this);
        System.out.println("[+] Demarrage de la vue Administrateur -> " + av);
    }

    /**
     * Pour creer une JTable
     * @param data Les donnees
     * @param title Les titres
     * */
    private JTable createJTable(Object[][] data, String[] title) {
        return new JTable(data, title) {
            public boolean editCellAt(int row, int column, java.util.EventObject e) {
                return false;
            }
        };
    }

    /**
     * Pour afficher une JTable sans listener
     *
     * @param parent La fenetre qui sera bloque
     * @param frameTitle Le titre de la fenetre
     * @param size_x Taille en x
     * @param size_y Taille en y
     * @param loca_x Localisation en x
     * @param loca_y Localisation en y
     * @param liste La JTable
     * */
    private void Display(BFrame parent, String frameTitle, int size_x, int size_y, int loca_x, int loca_y, JTable liste) {
        JPanel forModal = new JPanel();

        ListSelectionModel lsm = liste.getSelectionModel();
        liste.getTableHeader().setReorderingAllowed(false);
        liste.setFillsViewportHeight(true);

        this.currentJTableUse = liste;

        forModal.add(liste);

        BFrame frame = new BFrame(frameTitle, loca_x, loca_y, size_x, size_y, parent, forModal);
    }

    /**
     * Pour afficher une JTable contenant un listener
     *
     * @param parent La fenetre qui sera bloque
     * @param frameTitle Le titre de la fenetre
     * @param size_x Taille en x
     * @param size_y Taille en y
     * @param loca_x Localisation en x
     * @param loca_y Localisation en y
     * @param liste La JTable
     * */
    private void DisplayWithListner(BFrame parent, String frameTitle, int size_x, int size_y, int loca_x, int loca_y, JTable liste) {
        JPanel forModal = new JPanel();

        ListSelectionModel lsm = liste.getSelectionModel();
        lsm.addListSelectionListener(this);
        liste.getTableHeader().setReorderingAllowed(false);
        liste.setFillsViewportHeight(true);

        this.currentJTableUse = liste;

        forModal.add(liste);

        BFrame frame = new BFrame(frameTitle, loca_x, loca_y, size_x, size_y, parent, forModal);
    }

    /**
     * Pour afficher une modale classique pour plus de liberte (panel a creer au prealable)
     *
     * @param parent La fenetre qui sera bloque
     * @param frameTitle Le titre de la fenetre
     * @param size_x Taille en x
     * @param size_y Taille en y
     * @param loca_x Localisation en x
     * @param loca_y Localisation en y
     * @param forModal Le panel a mettre dans la fenetre (libre)
     * */
    private void DisplayModal(BFrame parent, String frameTitle, int size_x, int size_y, int loca_x, int loca_y, JPanel forModal, Object... data) {
        BFrame frame = new BFrame(frameTitle, loca_x, loca_y, size_x, size_y, parent, forModal);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        String command = e.getActionCommand();

        String groupeOption = this.pv.getComboSelection();
        int groupeIndex = this.pv.getComboSelectionIndex();
        String text = this.pv.getSearchStud();

        if(Objects.equals(command, "pv::GetStudList")) {
            String[][] data = new String[this.e.size()][2];

            String[] titre = {
                    "Nom",
                    "Prenom",
                    "Groupe"
            };

            for(int i = 0; i <= this.e.size()-1; i++) {
                String[] info = {
                        this.e.get(i).getNom(),
                        this.e.get(i).getPrenom(),
                        String.valueOf(this.e.get(i).getGroupe())
                };

                data[i] = info;
            }

            Display(
                    this.pv,
                    "Liste des etudiants",
                    350,
                    400,
                    this.pv.getX(),
                    this.pv.getY(),
                    this.createJTable(data, titre)
            );
        }

        else if(Objects.equals(command, "pv::GetListFiltered")) {
            String[][] data = new String[this.e.size()][1];

            String[] titre = {
                    "Nom",
                    "Prenom"
            };

            int i, j;

            for(i = 0, j = 0; i <= this.e.size()-1; i++) {
                if(this.e.get(i).getGroupe() == groupeIndex) {
                    String[] info = {
                            this.e.get(i).getNom(),
                            this.e.get(i).getPrenom()
                    };

                    data[j] = info;
                    j++;
                }
            }

            String[][] data_final = new String[j][1];
            for(int x = 0; x <= j-1; x++) {
                data_final[x] = data[x];
            }

            Display(
                    this.pv,
                    "Liste d'eleve du " + groupeOption,
                    350,
                    400,
                    this.pv.getX(),
                    this.pv.getY(),
                    this.createJTable(data_final, titre)
            );
        }

        else if(Objects.equals(command, "pv::SearchStudentPer3Letters")) {
            if(text.length() < 3 || text == null) {
                JOptionPane.showMessageDialog(
                        this.pv,
                        "Veuillez ecrire 3 lettres",
                        "Erreur.",
                        JOptionPane.ERROR_MESSAGE
                );
            } else {
                char[] beg = text.toCharArray();

                ArrayList<String> filtreEleveNom = db.fetchAll("SELECT nom FROM fi_eleves WHERE nom LIKE '" + beg[0] + beg[1] + beg[2] + "%'");
                ArrayList<String> filtreElevePrenom = db.fetchAll("SELECT prenom FROM fi_eleves WHERE nom LIKE '" + beg[0] + beg[1] + beg[2] + "%'");
                ArrayList<String> filtreEleveGroupe = db.fetchAll("SELECT groupe FROM fi_eleves WHERE nom LIKE '" + beg[0] + beg[1] + beg[2] + "%'");

                System.out.println(filtreEleveGroupe.size() + filtreElevePrenom.size() + filtreEleveGroupe.size());

                if(filtreEleveGroupe.size() == 0 || filtreEleveNom.size() == 0 || filtreElevePrenom.size() == 0) {
                    JOptionPane.showMessageDialog(
                            this.pv,
                            "Eleve introuvable !",
                            "Erreur.",
                            JOptionPane.ERROR_MESSAGE
                    );
                } else {
                    String[] titre = {
                            "Nom",
                            "Prenom",
                            "Groupe"
                    };

                    String[][] data = new String[filtreEleveNom.size()][2];

                    for(int i = 0; i <= filtreEleveNom.size()-1; i++){
                        data[i] = new String[]{
                                filtreEleveNom.get(i),
                                filtreElevePrenom.get(i),
                                String.valueOf(filtreEleveGroupe.get(i))
                        };
                    }

                    Display(
                            this.pv,
                            "Recherche",
                            350,
                            400,
                            this.pv.getX(),
                            this.pv.getY(),
                            this.createJTable(data, titre)
                    );
                }
            }
        }

        else if(Objects.equals(command, "av::MoveStudGrup")) {
            Object[][] data = new Object[this.e.size()][3];

            String[] titre = {
                    "Nom",
                    "Prenom",
                    "Groupe",
                    "Action"
            };

            for(int i = 0; i <= this.e.size()-1; i++) {
                Object[] info = {
                        this.e.get(i).getNom(),
                        this.e.get(i).getPrenom(),
                        String.valueOf(this.e.get(i).getGroupe()),
                        "[DEPLACER]"
                };

                data[i] = info;
            }

            DisplayWithListner(
                    this.av,
                    "Deplacer un etudiant",
                    350,
                    400,
                    this.av.getX(),
                    this.av.getY(),
                    this.createJTable(data, titre)
            );
        }
    }

    @Override
    public void valueChanged(ListSelectionEvent e) {
        if(!e.getValueIsAdjusting()) {
            int[] cell = this.currentJTableUse.getSelectedRows();
            int collumnCount = this.currentJTableUse.getColumnCount();
            Object value;
            System.out.println(e.getSource());

            if(cell.length > 0) {
                for(int i = 0; i < collumnCount; i++) {
                    TableModel tm = this.currentJTableUse.getModel();
                    value = tm.getValueAt(cell[0], i);

                    if(Objects.equals(value, "[DEPLACER]")) {
                        JPanel forModal = new JPanel(new GridBagLayout());
                        BLayout settings = new BLayout();

                        JLabel l = new JLabel("test");
                        forModal.add(l);

                        DisplayModal(
                                this.av,
                                "Deplacer l'eleve : " + tm.getValueAt(cell[0], 0) + " " + tm.getValueAt(cell[0], 1),
                                500,
                                250,
                                this.av.getX(),
                                this.av.getY(),
                                forModal,

                                /**
                                 * Position toujours similaire { cell[0] = Nom (String), cell[1] = Prenom (String), cell[2] = Groupe (String) }
                                 */
                                tm.getValueAt(cell[0], 0),
                                tm.getValueAt(cell[0], 1),
                                tm.getValueAt(cell[0], 2)
                        );
                    }
                }
            }
        }
    }
}