package org.example.petshopdesktop.controllers.dialogcontrollers;

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.TextField;
import javafx.scene.input.MouseEvent;
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.inventory.InventoryRequest;
import org.example.petshopdesktop.api.dto.inventory.InventoryResponse;
import org.example.petshopdesktop.api.dto.product.ProductResponse;
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.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

public class InventoryDialogController {

    //FXML elements
    @FXML
    private Button btnCancel;

    @FXML
    private Button btnSave;

    @FXML
    private ComboBox<Product> cbProduct;

    @FXML
    private Label lblInventoryId;

    @FXML
    private Label lblMode;

    @FXML
    private TextField txtQuantity;

    //Determines if the mode is add or edit
    private String mode = null;

    //Loads upon .FXML boot
    @FXML
    void initialize() {
        cbProduct.setConverter(new StringConverter<Product>() {

            //Displays product in combobox (prodID + name)
            @Override
            public String toString(Product product) {
                return product == null ? "" : product.getProdId() + ": " + product.getProdName();
            }

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

        //Load product list from API into combobox
        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");
            System.out.println("Error loading products: " + e.getMessage());
        }

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

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

    //Handles save button click event
    private void buttonSaveClicked(MouseEvent mouseEvent) {
        int numRow = 0;
        String errorMsg = "";

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

        //Validate inputs
        errorMsg += Validator.isPresent(txtQuantity.getText(), "Quantity");
        errorMsg += Validator.isLessThanVarChars(txtQuantity.getText(), "Quantity", 11);
        errorMsg += Validator.isNonNegativeInteger(txtQuantity.getText(), "Quantity");

        //Operation only occurs if there are no errors
        if (errorMsg.isEmpty()) {
            try {
                InventoryRequest request = new InventoryRequest();
                Product selectedProduct = cbProduct.getSelectionModel().getSelectedItem();
                Long storeId = UserSession.getInstance().getStoreId();
                if (storeId == null || storeId <= 0) {
                    throw new IllegalStateException("Store is not set for this account");
                }
                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();
            }
        }

        //Displays validation errors
        else {
            Alert alert = new Alert(Alert.AlertType.ERROR);
            alert.setHeaderText("Input Error");
            alert.setContentText(errorMsg);
            alert.showAndWait();
        }
    }

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

    //Editing
    //Displays fields with existing inventory data
    public void displayInventoryDetails(Inventory inventory) {
        if (inventory != null) {

            //Displays inventory ID
            lblInventoryId.setText("ID: " + inventory.getInventoryId());

            //Selecting matching product in combobox
            for (Product product : cbProduct.getItems()) {
                if (product.getProdId() == inventory.getProdId()) {
                    cbProduct.getSelectionModel().select(product);
                    break;
                }
            }

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

    //Sets dialog view to add/edit. Updates UI labels
    public void setMode(String mode) {
        this.mode = mode;
        lblMode.setText(mode + " Inventory");
        lblInventoryId.setVisible(mode.equals("Edit"));
    }
}
