package ui;

import java.io.File;
import java.util.List;

import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import model.PersonMapping;
import db.UserDAO;

public class ConfigUI extends BorderPane {

    private final TextField dbPathField = new TextField();
    private final Button chooseDbButton = new Button("…");
    private final Button reloadButton = new Button("Neu laden");

    private final MainUI mainUI;

    // Userverwaltung-Elemente
    private final TableView<UserEntry> userTable = new TableView<>();
    private final TextField kuerzelField = new TextField();
    private final TextField nameField = new TextField();
    private final Button saveButton = new Button("Speichern");
    private final Button deleteButton = new Button("Löschen");

    private final UserDAO userDAO = new UserDAO(util.Config.getDbPath());
    private final String currentLogin = System.getProperty("user.name").toLowerCase();

    public ConfigUI(Stage stage, MainUI mainUI) {
        this.mainUI = mainUI;
        setPadding(new Insets(15));

        // --------- DB-Pfad UI ---------
        GridPane grid = new GridPane();
        grid.setVgap(8);
        grid.setHgap(10);

        Label label = new Label("Pfad zur Datenbankdatei:");
        dbPathField.setText(util.Config.getDbPath());
        dbPathField.setPrefWidth(400);

        chooseDbButton.setOnAction(e -> {
            FileChooser fileChooser = new FileChooser();
            fileChooser.setTitle("SQLite-Datenbank auswählen");
            fileChooser.getExtensionFilters().add(
                    new FileChooser.ExtensionFilter("SQLite DB", "*.db", "*.sqlite"));
            File file = fileChooser.showOpenDialog(stage);
            if (file != null) {
                String newPath = file.getAbsolutePath();
                dbPathField.setText(newPath);
                util.Config.saveDbPathFromUI(newPath);
                mainUI.reloadDatabaseDependentData();
            }
        });

        reloadButton.setOnAction(e -> {
            util.Config.load();
            dbPathField.setText(util.Config.getDbPath());
            mainUI.reloadDatabaseDependentData();
            Alert alert = new Alert(Alert.AlertType.INFORMATION,
                    "Konfiguration neu geladen:\n" + util.Config.getDbPath());
            alert.setHeaderText(null);
            alert.showAndWait();
        });

        grid.add(label, 0, 0);
        grid.add(new HBox(5, dbPathField, chooseDbButton, reloadButton), 1, 0);

        // --------- User-Verwaltung ---------
        VBox userBox = new VBox(15);
        userBox.setPadding(new Insets(30, 0, 0, 0));
        userBox.getChildren().add(new Separator());

        boolean isAdmin = PersonMapping.isAdmin(currentLogin);

        if (isAdmin) {
            Label heading = new Label("Benutzerverwaltung (Admin)");
            heading.setStyle("-fx-font-size: 15; -fx-font-weight: bold;");
            userBox.getChildren().add(heading);

            TableColumn<UserEntry, String> kuerzelCol = new TableColumn<>("Kürzel");
            kuerzelCol.setCellValueFactory(data -> data.getValue().kuerzelProperty());

            TableColumn<UserEntry, String> nameCol = new TableColumn<>("Name");
            nameCol.setCellValueFactory(data -> data.getValue().nameProperty());

            kuerzelCol.setPrefWidth(120);
            nameCol.setPrefWidth(250);

            userTable.getColumns().addAll(kuerzelCol, nameCol);
            refreshUserList();

            // Auswahl -> Felder füllen
            userTable.getSelectionModel().selectedItemProperty().addListener((obs, old, sel) -> {
                if (sel != null) {
                    kuerzelField.setText(sel.getKuerzel());
                    nameField.setText(sel.getName());
                }
            });

            HBox editor = new HBox(8,
                    new Label("Kürzel:"), kuerzelField,
                    new Label("Name:"), nameField,
                    saveButton, deleteButton
            );
            editor.setPadding(new Insets(10, 0, 0, 0));

            saveButton.setOnAction(e -> saveUser());
            deleteButton.setOnAction(e -> deleteUser());

            userBox.getChildren().addAll(userTable, editor);

        } else {
            Label heading = new Label("Eigener Eintrag");
            heading.setStyle("-fx-font-size: 15; -fx-font-weight: bold;");
            userBox.getChildren().add(heading);

            kuerzelField.setText(currentLogin);
            kuerzelField.setEditable(false);

            String currentName = PersonMapping.toName(currentLogin);
            if (currentName != null && !currentName.equals(currentLogin)) {
                nameField.setText(currentName);
            }

            saveButton.setOnAction(e -> saveOwnUser());

            GridPane userGrid = new GridPane();
            userGrid.setVgap(8);
            userGrid.setHgap(10);
            userGrid.add(new Label("Kürzel:"), 0, 0); userGrid.add(kuerzelField, 1, 0);
            userGrid.add(new Label("Name:"), 0, 1); userGrid.add(nameField, 1, 1);
            userGrid.add(saveButton, 1, 2);

            userBox.getChildren().add(userGrid);
        }

        VBox vbox = new VBox(15, grid, userBox);
        setCenter(vbox);
    }

    private void refreshUserList() {
        ObservableList<UserEntry> users = FXCollections.observableArrayList();
        for (String[] entry : userDAO.getAllUsers()) {
            users.add(new UserEntry(entry[0], entry[1]));
        }
        userTable.setItems(users);
    }

    private void saveUser() {
        String k = kuerzelField.getText().trim().toLowerCase();
        String n = nameField.getText().trim();
        if (k.isEmpty() || n.isEmpty()) {
            showAlert("Bitte Kürzel und Name eingeben.");
            return;
        }
        boolean ok = userDAO.saveUser(k, n); // NEU: insert or update je nach Existenz
        PersonMapping.forceReloadPeople();
        refreshUserList();  
        showAlert(ok ? "Gespeichert. Änderung nach Neustart verfügbar." : "Fehler beim Speichern.");
        PersonMapping.forceReloadPeople();
    }

    private void saveOwnUser() {
        String k = kuerzelField.getText().trim().toLowerCase();
        String n = nameField.getText().trim();
        if (n.isEmpty()) {
            showAlert("Bitte Namen eingeben.");
            return;
        }
        boolean ok = userDAO.saveUser(k, n); // NEU: insert or update je nach Existenz
        PersonMapping.forceReloadPeople();
        refreshUserList();  
        showAlert(ok ? "Gespeichert. Änderung nach Neustart verfügbar." : "Fehler beim Speichern.");
    }

    private void deleteUser() {
        String k = kuerzelField.getText().trim().toLowerCase();
        if (k.isEmpty()) return;
        userDAO.deleteUser(k);
        refreshUserList();
        showAlert("Gelöscht.");
    }
    
    private void showAlert(String text) {
        Alert alert = new Alert(Alert.AlertType.INFORMATION, text);
        alert.setHeaderText(null);
        alert.showAndWait();
    }

    // --------- Hilfsklasse für TableView ---------
    public static class UserEntry {
        private final StringProperty kuerzel = new SimpleStringProperty();
        private final StringProperty name = new SimpleStringProperty();

        public UserEntry(String kuerzel, String name) {
            this.kuerzel.set(kuerzel);
            this.name.set(name);
        }

        public String getKuerzel() { return kuerzel.get(); }
        public String getName() { return name.get(); }
        public StringProperty kuerzelProperty() { return kuerzel; }
        public StringProperty nameProperty() { return name; }
    }
}