package org.example.petshopdesktop.controllers;

import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import org.example.petshopdesktop.api.dto.activity.ActivityLogResponse;
import org.example.petshopdesktop.api.endpoints.ActivityLogApi;
import org.example.petshopdesktop.util.ActivityLogger;
import org.example.petshopdesktop.util.TableViewSupport;

import java.time.format.DateTimeFormatter;
import java.util.List;

public class ActivityLogController {

    @FXML
    private TableView<ActivityLogResponse> tvActivityLogs;

    @FXML
    private TableColumn<ActivityLogResponse, Object> colTimestamp;

    @FXML
    private TableColumn<ActivityLogResponse, String> colUser;

    @FXML
    private TableColumn<ActivityLogResponse, String> colRole;

    @FXML
    private TableColumn<ActivityLogResponse, String> colStore;

    @FXML
    private TableColumn<ActivityLogResponse, String> colActivity;

    @FXML
    private Button btnRefresh;

    @FXML
    private Label lblStatus;

    @FXML
    private Label lblError;

    private final ObservableList<ActivityLogResponse> activityLogs = FXCollections.observableArrayList();
    private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    private static final int DEFAULT_LIMIT = 2000;

    @FXML
    public void initialize() {
        colTimestamp.setCellValueFactory(data -> new javafx.beans.property.SimpleObjectProperty<>(data.getValue().getLogTimestamp()));
        colTimestamp.setCellFactory(column -> new javafx.scene.control.TableCell<>() {
            @Override
            protected void updateItem(Object item, boolean empty) {
                super.updateItem(item, empty);
                if (empty || item == null) {
                    setText(null);
                } else if (item instanceof java.time.LocalDateTime time) {
                    setText(time.format(formatter));
                } else {
                    setText(item.toString());
                }
            }
        });
        colUser.setCellValueFactory(data -> new javafx.beans.property.SimpleStringProperty(displayUser(data.getValue())));
        colRole.setCellValueFactory(data -> new javafx.beans.property.SimpleStringProperty(displayRole(data.getValue())));
        colStore.setCellValueFactory(data -> new javafx.beans.property.SimpleStringProperty(displayStore(data.getValue())));
        colActivity.setCellValueFactory(data -> new javafx.beans.property.SimpleStringProperty(nullToBlank(data.getValue().getActivity())));

        TableViewSupport.bindSortedItems(tvActivityLogs, new javafx.collections.transformation.FilteredList<>(activityLogs, a -> true));
        loadLogs();
    }

    @FXML
    void btnRefreshClicked(ActionEvent event) {
        loadLogs();
    }

    private void loadLogs() {
        lblError.setText("");
        tvActivityLogs.setDisable(true);
        btnRefresh.setDisable(true);

        new Thread(() -> {
            try {
                List<ActivityLogResponse> content = ActivityLogApi.getInstance().getActivityLogs(DEFAULT_LIMIT);
                List<ActivityLogResponse> safeContent = content != null ? content : List.of();

                Platform.runLater(() -> {
                    activityLogs.setAll(safeContent);
                    tvActivityLogs.setDisable(false);
                    btnRefresh.setDisable(false);
                    TableViewSupport.flashStatus(lblStatus, "Refreshed");
                });
            } catch (Exception e) {
                ActivityLogger.getInstance().logException("ActivityLogController.loadLogs", e, "Loading activity logs");
                Platform.runLater(() -> {
                    lblError.setText(e.getMessage() == null || e.getMessage().isBlank()
                        ? "Could not load activity logs."
                        : "Could not load activity logs: " + e.getMessage());
                    tvActivityLogs.setDisable(false);
                    btnRefresh.setDisable(false);
                });
            }
        }).start();
    }

    private String displayUser(ActivityLogResponse log) {
        if (log == null) {
            return "";
        }
        if (log.getFullNameSnapshot() != null && !log.getFullNameSnapshot().isBlank()) {
            return log.getFullNameSnapshot();
        }
        if (log.getFullName() != null && !log.getFullName().isBlank()) {
            return log.getFullName();
        }
        if (log.getUsernameSnapshot() != null && !log.getUsernameSnapshot().isBlank()) {
            return log.getUsernameSnapshot();
        }
        if (log.getUsername() != null && !log.getUsername().isBlank()) {
            return log.getUsername();
        }
        return log.getUserId() != null ? String.valueOf(log.getUserId()) : "";
    }

    private String displayRole(ActivityLogResponse log) {
        if (log == null) {
            return "";
        }
        if (log.getRoleSnapshot() != null && !log.getRoleSnapshot().isBlank()) {
            return log.getRoleSnapshot();
        }
        return nullToBlank(log.getRole());
    }

    private String displayStore(ActivityLogResponse log) {
        if (log == null) {
            return "";
        }
        if (log.getStoreNameSnapshot() != null && !log.getStoreNameSnapshot().isBlank()) {
            return log.getStoreNameSnapshot();
        }
        return nullToBlank(log.getStoreName());
    }

    private String nullToBlank(String value) {
        return value == null ? "" : value;
    }
}
