package org.example.petshopdesktop.controllers.dialogcontrollers;

import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.TextField;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.StringConverter;
import org.example.petshopdesktop.models.Inventory;
import org.example.petshopdesktop.Validator;
import org.example.petshopdesktop.api.dto.common.DropdownOption;
import org.example.petshopdesktop.api.dto.inventory.InventoryRequest;
import org.example.petshopdesktop.api.dto.product.ProductResponse;
import org.example.petshopdesktop.api.endpoints.DropdownApi;
import org.example.petshopdesktop.api.endpoints.InventoryApi;
import org.example.petshopdesktop.api.endpoints.ProductApi;
import org.example.petshopdesktop.auth.UserSession;
import org.example.petshopdesktop.models.Product;
import org.example.petshopdesktop.util.ActivityLogger;

import java.util.List;

public class InventoryDialogController {

    @FXML private Button btnCancel;
    @FXML private Button btnSave;
    @FXML private ComboBox<Product> cbProduct;
    @FXML private ComboBox<DropdownOption> cbStore;
    @FXML private VBox vbStoreField;
    @FXML private Label lblInventoryId;
    @FXML private Label lblMode;
    @FXML private TextField txtQuantity;

    private String mode = null;
    private Long pendingStoreId = null;

    @FXML
    void initialize() {
        cbProduct.setConverter(new StringConverter<Product>() {
            @Override
            public String toString(Product product) {
                return product == null ? "" : product.getProdId() + ": " + product.getProdName();
            }

            @Override
            public Product fromString(String string) { return null; }
        });

        cbStore.setCellFactory(param -> new ListCell<>() {
            @Override protected void updateItem(DropdownOption o, boolean empty) {
                super.updateItem(o, empty);
                setText(empty || o == null ? null : o.getLabel());
            }
        });
        cbStore.setButtonCell(new ListCell<>() {
            @Override protected void updateItem(DropdownOption o, boolean empty) {
                super.updateItem(o, empty);
                setText(empty || o == null ? null : o.getLabel());
            }
        });

        try {
            List<ProductResponse> productResponses = ProductApi.getInstance().listProducts(null);
            if (productResponses != null) {
                ObservableList<Product> products = FXCollections.observableArrayList();
                for (ProductResponse pr : productResponses) {
                    products.add(new Product(
                        pr.getProdId().intValue(),
                        pr.getProdName(),
                        pr.getProdPrice().doubleValue(),
                        0,
                        pr.getProdDesc()
                    ));
                }
                cbProduct.setItems(products);
            }
        } catch (Exception e) {
            ActivityLogger.getInstance().logException(
                "InventoryDialogController.initialize",
                e,
                "Loading products for combo box");
        }

        boolean isAdmin = UserSession.getInstance().isAdmin();
        if (isAdmin) {
            loadStores();
        } else {
            vbStoreField.setManaged(false);
            vbStoreField.setVisible(false);
        }

        btnSave.setOnMouseClicked(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent mouseEvent) {
                buttonSaveClicked(mouseEvent);
            }
        });

        btnCancel.setOnMouseClicked(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent mouseEvent) {
                closeStage(mouseEvent);
            }
        });
    }

    private void loadStores() {
        new Thread(() -> {
            try {
                List<DropdownOption> stores = DropdownApi.getInstance().getStores();
                Platform.runLater(() -> {
                    cbStore.setItems(FXCollections.observableArrayList(stores));
                    applyPendingStore();
                });
            } catch (Exception e) {
                ActivityLogger.getInstance().logException("InventoryDialogController.loadStores", e, "Loading stores");
                Platform.runLater(() -> {
                    cbStore.setDisable(true);
                    cbStore.setPromptText("Unable to load stores");
                });
            }
        }).start();
    }

    private void applyPendingStore() {
        if (pendingStoreId == null) return;
        for (DropdownOption opt : cbStore.getItems()) {
            if (opt.getId() != null && opt.getId().equals(pendingStoreId)) {
                cbStore.setValue(opt);
                pendingStoreId = null;
                return;
            }
        }
    }

    private void buttonSaveClicked(MouseEvent mouseEvent) {
        String errorMsg = "";

        if (cbProduct.getSelectionModel().getSelectedItem() == null) {
            errorMsg += "Product is required.\n";
        }

        errorMsg += Validator.isPresent(txtQuantity.getText(), "Quantity");
        errorMsg += Validator.isLessThanVarChars(txtQuantity.getText(), "Quantity", 11);
        errorMsg += Validator.isPositiveInteger(txtQuantity.getText(), "Quantity");

        boolean isAdmin = UserSession.getInstance().isAdmin();
        Long storeId;
        if (isAdmin) {
            if (cbStore.getValue() == null) {
                errorMsg += "Store is required.\n";
                storeId = null;
            } else {
                storeId = cbStore.getValue().getId();
            }
        } else {
            storeId = UserSession.getInstance().getStoreId();
            if (storeId == null || storeId <= 0) {
                errorMsg += "Store is not set for this account.\n";
            }
        }

        if (errorMsg.isEmpty()) {
            try {
                InventoryRequest request = new InventoryRequest();
                Product selectedProduct = cbProduct.getSelectionModel().getSelectedItem();
                request.setProdId((long) selectedProduct.getProdId());
                int quantity;
                try {
                    quantity = Integer.parseInt(txtQuantity.getText());
                } catch (NumberFormatException e) {
                    throw new IllegalArgumentException("Invalid quantity format");
                }
                request.setQuantity(quantity);
                request.setStoreId(storeId);

                if (mode.equals("Add")) {
                    InventoryApi.getInstance().createInventory(request);
                } else {
                    String[] parts = lblInventoryId.getText().split(": ");
                    if (parts.length < 2) {
                        throw new IllegalStateException("Invalid inventory ID format");
                    }
                    Long inventoryId = Long.parseLong(parts[1]);
                    InventoryApi.getInstance().updateInventory(inventoryId, request);
                }

                Alert alert = new Alert(Alert.AlertType.INFORMATION);
                alert.setHeaderText("Saved");
                alert.setContentText(mode + " succeeded");
                alert.showAndWait();
                closeStage(mouseEvent);
            } catch (Exception e) {
                ActivityLogger.getInstance().logException(
                    "InventoryDialogController.buttonSaveClicked",
                    e,
                    mode + " inventory");
                Alert alert = new Alert(Alert.AlertType.ERROR);
                alert.setHeaderText("Database Operation Error");
                alert.setContentText(e.getMessage());
                alert.showAndWait();
            }
        } else {
            Alert alert = new Alert(Alert.AlertType.ERROR);
            alert.setHeaderText("Input Error");
            alert.setContentText(errorMsg);
            alert.showAndWait();
        }
    }

    private void closeStage(MouseEvent mouseEvent) {
        Node node = (Node) mouseEvent.getSource();
        Stage stage = (Stage) node.getScene().getWindow();
        stage.close();
    }

    public void displayInventoryDetails(Inventory inventory) {
        if (inventory != null) {
            lblInventoryId.setText("ID: " + inventory.getInventoryId());

            for (Product product : cbProduct.getItems()) {
                if (product.getProdId() == inventory.getProdId()) {
                    cbProduct.getSelectionModel().select(product);
                    break;
                }
            }

            txtQuantity.setText(String.valueOf(inventory.getQuantity()));

            boolean isAdmin = UserSession.getInstance().isAdmin();
            if (isAdmin && inventory.getStoreId() > 0) {
                pendingStoreId = (long) inventory.getStoreId();
                applyPendingStore();
            }
        }
    }

    public void setMode(String mode) {
        this.mode = mode;
        lblMode.setText(mode + " Inventory");
        lblInventoryId.setVisible(mode.equals("Edit"));
    }
}
