package de.votian.web.view;

import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.combobox.ComboBox;
import com.vaadin.flow.component.dialog.Dialog;
import com.vaadin.flow.component.formlayout.FormLayout;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.icon.VaadinIcon;
import com.vaadin.flow.component.notification.Notification;
import com.vaadin.flow.component.notification.NotificationVariant;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import de.votian.web.model.SessionData;
import de.votian.web.service.RestClientService;

import java.util.*;

@Route(value = "costcenters", layout = MainLayout.class)
@PageTitle("Votian - Kostenstellen")
public class CostCenterView extends VerticalLayout {

    private final RestClientService restClient;
    private final SessionData sessionData;
    private final Grid<Map<String, Object>> grid;
    private final TextField customerIdField;

    public CostCenterView(RestClientService restClient, SessionData sessionData) {
        this.restClient = restClient;
        this.sessionData = sessionData;
        setSizeFull();
        setPadding(true);

        customerIdField = new TextField("Kunden-ID");
        customerIdField.setPlaceholder("Kunden-ID eingeben...");

        Button loadButton = new Button("Laden", VaadinIcon.DOWNLOAD.create(), e -> loadCostCenters());
        loadButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY);

        Button addButton = new Button("Neue Kostenstelle", VaadinIcon.PLUS.create(), e -> showAddDialog());
        addButton.setVisible(sessionData.canManageCostCenters());

        HorizontalLayout toolbar = new HorizontalLayout(customerIdField, loadButton, addButton);
        toolbar.setAlignItems(Alignment.BASELINE);

        grid = new Grid<>();
        grid.addColumn(m -> m.get("id")).setHeader("ID").setAutoWidth(true);
        grid.addColumn(m -> m.get("name")).setHeader("Name").setFlexGrow(2);
        grid.addColumn(m -> m.get("path")).setHeader("Pfad").setFlexGrow(2);
        grid.addColumn(m -> "1".equals(str(m.get("visible"))) ? "Ja" : "Nein").setHeader("Sichtbar").setAutoWidth(true);
        grid.addColumn(m -> "1".equals(str(m.get("isExtern"))) ? "Ja" : "Nein").setHeader("Extern").setAutoWidth(true);
        grid.setSizeFull();

        grid.addItemDoubleClickListener(e -> showEditDialog(e.getItem()));

        add(toolbar, grid);

        if (sessionData.isCustomerUser() && sessionData.getCustomerId() != null) {
            customerIdField.setValue(String.valueOf(sessionData.getCustomerId()));
            customerIdField.setReadOnly(true);
            loadCostCenters();
        }
    }

    private void loadCostCenters() {
        String csId = customerIdField.getValue().trim();
        if (csId.isEmpty()) {
            Notification.show("Bitte Kunden-ID eingeben.");
            return;
        }
        try {
            Object[] centers = restClient.get("/costcenters/customer/" + csId, Object[].class);
            if (centers != null) {
                List<Map<String, Object>> items = new ArrayList<>();
                for (Object c : centers) {
                    if (c instanceof Map) {
                        @SuppressWarnings("unchecked")
                        Map<String, Object> map = (Map<String, Object>) c;
                        Long id = map.get("id") instanceof Number number ? number.longValue() : null;
                        if (!sessionData.isCustomerUser() || sessionData.hasCostCenterAccess(id)) {
                            items.add(map);
                        }
                    }
                }
                grid.setItems(items);
            }
        } catch (Exception e) {
            Notification.show("Fehler: " + e.getMessage());
        }
    }

    private void showAddDialog() {
        if (!sessionData.canManageCostCenters()) {
            Notification.show("Keine Berechtigung zum Anlegen von Kostenstellen.");
            return;
        }
        String csId = customerIdField.getValue().trim();
        if (csId.isEmpty()) {
            Notification.show("Bitte zuerst Kunden-ID eingeben.");
            return;
        }

        Dialog dialog = new Dialog();
        dialog.setHeaderTitle("Neue Kostenstelle");
        dialog.setWidth("500px");

        TextField nameField = new TextField("Name");
        nameField.setWidthFull();
        TextField pathField = new TextField("Pfad");
        pathField.setWidthFull();
        ComboBox<String> visibleField = new ComboBox<>("Sichtbar");
        visibleField.setItems("0", "1");
        visibleField.setItemLabelGenerator(v -> "1".equals(v) ? "Ja" : "Nein");
        visibleField.setValue("1");

        FormLayout form = new FormLayout(nameField, pathField, visibleField);
        dialog.add(form);

        Button saveBtn = new Button("Speichern", ev -> {
            try {
                Map<String, Object> csc = new HashMap<>();
                csc.put("customerId", Long.parseLong(csId));
                csc.put("name", nameField.getValue());
                csc.put("path", pathField.getValue());
                csc.put("visible", visibleField.getValue());
                restClient.post("/costcenters", csc, LinkedHashMap.class);
                Notification.show("Kostenstelle gespeichert!", 3000, Notification.Position.MIDDLE)
                        .addThemeVariants(NotificationVariant.LUMO_SUCCESS);
                dialog.close();
                loadCostCenters();
            } catch (Exception ex) {
                Notification.show("Fehler: " + ex.getMessage());
            }
        });
        saveBtn.addThemeVariants(ButtonVariant.LUMO_PRIMARY);

        Button cancelBtn = new Button("Abbrechen", ev -> dialog.close());
        dialog.getFooter().add(cancelBtn, saveBtn);
        dialog.open();
    }

    private void showEditDialog(Map<String, Object> item) {
        if (!sessionData.canManageCostCenters()) {
            Notification.show("Keine Berechtigung zum Bearbeiten von Kostenstellen.");
            return;
        }
        Dialog dialog = new Dialog();
        dialog.setHeaderTitle("Kostenstelle bearbeiten");
        dialog.setWidth("500px");

        TextField nameField = new TextField("Name");
        nameField.setValue(str(item.get("name")));
        nameField.setWidthFull();

        TextField pathField = new TextField("Pfad");
        pathField.setValue(str(item.get("path")));
        pathField.setWidthFull();

        ComboBox<String> visibleField = new ComboBox<>("Sichtbar");
        visibleField.setItems("0", "1");
        visibleField.setItemLabelGenerator(v -> "1".equals(v) ? "Ja" : "Nein");
        visibleField.setValue(str(item.get("visible")));

        FormLayout form = new FormLayout(nameField, pathField, visibleField);
        dialog.add(form);

        Button saveBtn = new Button("Speichern", ev -> {
            try {
                Map<String, Object> updates = new HashMap<>();
                updates.put("name", nameField.getValue());
                updates.put("path", pathField.getValue());
                updates.put("visible", visibleField.getValue());
                restClient.put("/costcenters/" + item.get("id"), updates);
                Notification.show("Gespeichert!", 3000, Notification.Position.MIDDLE)
                        .addThemeVariants(NotificationVariant.LUMO_SUCCESS);
                dialog.close();
                loadCostCenters();
            } catch (Exception ex) {
                Notification.show("Fehler: " + ex.getMessage());
            }
        });
        saveBtn.addThemeVariants(ButtonVariant.LUMO_PRIMARY);

        Button cancelBtn = new Button("Abbrechen", ev -> dialog.close());
        dialog.getFooter().add(cancelBtn, saveBtn);
        dialog.open();
    }

    private String str(Object obj) {
        return obj != null ? obj.toString() : "";
    }
}
