package org.example.petshopdesktop.controllers.dialogcontrollers;

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.Label;
import javafx.scene.control.TextField;
import javafx.scene.input.MouseEvent;
import javafx.stage.Stage;
import org.example.petshopdesktop.Validator;
import org.example.petshopdesktop.api.dto.supplier.SupplierRequest;
import org.example.petshopdesktop.api.dto.supplier.SupplierResponse;
import org.example.petshopdesktop.api.endpoints.SupplierApi;
import org.example.petshopdesktop.models.Supplier;
import org.example.petshopdesktop.util.ActivityLogger;
import org.example.petshopdesktop.util.TextFieldFormatSupport;

public class SupplierDialogController {

    @FXML
    private Button btnCancel;

    @FXML
    private Button btnSave;

    @FXML
    private Label lblMode;

    @FXML
    private Label lblSupId;

    @FXML
    private TextField txtCompanyName;

    @FXML
    private TextField txtContactFirstName;

    @FXML
    private TextField txtContactLastName;

    @FXML
    private TextField txtEmail;

    @FXML
    private TextField txtPhone;

    private String mode = null;

    /**
     * Add event listeners to buttons when dialog loads
     */
    @FXML
    void initialize() {
        TextFieldFormatSupport.applyPhoneNumberFormat(txtPhone);

        //Set up mouse handlers for buttons
        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);
            }
        });
    }

    /**
     * Validates the inputs, then add or update the database depending
     * on the mode
     * @param mouseEvent click event for save button
     */
    private void buttonSaveClicked(MouseEvent mouseEvent) {
        String errorMsg = ""; //error message for validation

        //Check validation (input required)
        errorMsg += Validator.isPresent(txtCompanyName.getText(), "Company Name");
        errorMsg += Validator.isPresent(txtContactFirstName.getText(), "Contact First Name");
        errorMsg += Validator.isPresent(txtContactLastName.getText(), "Contact Last Name");
        errorMsg += Validator.isPresent(txtEmail.getText(), "Email Address");
        errorMsg += Validator.isPresent(txtPhone.getText(), "Phone Number");

        //Check validation (Length size)
        errorMsg += Validator.isLessThanVarChars(txtCompanyName.getText(),"Company Name", 100);
        errorMsg += Validator.isLessThanVarChars(txtContactFirstName.getText(), "Contact First Name", 50);
        errorMsg += Validator.isLessThanVarChars(txtContactLastName.getText(), "Contact Last Name", 50);
        errorMsg += Validator.isLessThanVarChars(txtEmail.getText(), "Email Address", 100);

        //Check validation (format)
        errorMsg += Validator.isValidEmail(txtEmail.getText(), "Email Address");
        errorMsg += Validator.isValidPhoneNumber(txtPhone.getText(), "Phone Number");

        if(errorMsg.isEmpty()){ //no validation errors detected
            SupplierRequest request = createSupplierRequest();
            try {
                if (mode.equals("Add")) {
                    SupplierApi.getInstance().createSupplier(request);
                } else {
                    String[] parts = lblSupId.getText().split(": ");
                    if (parts.length < 2) {
                        throw new IllegalStateException("Invalid supplier ID format");
                    }
                    Long supplierId = Long.parseLong(parts[1]);
                    SupplierApi.getInstance().updateSupplier(supplierId, 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(
                    "SupplierDialogController.buttonSaveClicked",
                    e,
                    mode.equals("Add") ? "Inserting new supplier record" : "Updating supplier record");
                Alert alert = new Alert(Alert.AlertType.ERROR);
                alert.setHeaderText("Database Operation Error");
                alert.setContentText(mode + " failed: " + e.getMessage());
                alert.showAndWait();
            }
        }
        else{ //Display validation errors
            Alert alert = new Alert(Alert.AlertType.ERROR);
            alert.setHeaderText("Input Error");
            alert.setContentText(errorMsg);
            alert.showAndWait();
        }
    }

    /**
     * Close the window
     * @param mouseEvent mouse event to close
     */
    private void closeStage(MouseEvent mouseEvent) {
        Node node = (Node) mouseEvent.getSource();
        Stage stage = (Stage) node.getScene().getWindow();
        stage.close();
    }

    /**
     * Create a supplier request from the form inputs
     * @return supplier request for API call
     */
    private SupplierRequest createSupplierRequest(){
        SupplierRequest request = new SupplierRequest();
        request.setSupCompany(txtCompanyName.getText());
        request.setSupContactFirstName(txtContactFirstName.getText());
        request.setSupContactLastName(txtContactLastName.getText());
        request.setSupEmail(txtEmail.getText());
        request.setSupPhone(txtPhone.getText());
        return request;
    }

    /**
     * Display the supplier data in text fields
     * @param supplier the supplier entity containing data to display
     */
    public void displaySupplierDetails(Supplier supplier){
        if (supplier!=null){
            lblSupId.setText("ID: " + supplier.getSupId());
            txtCompanyName.setText(supplier.getSupCompany());
            txtContactFirstName.setText(supplier.getSupContactFirstName());
            txtContactLastName.setText(supplier.getSupContactLastName());
            txtEmail.setText(supplier.getSupEmail());
            txtPhone.setText(supplier.getSupPhone());
        }
    }


    /**
     * Set the mode of the dialog
     * @param mode the mode to for the dialog
     */
    public void setMode(String mode) {
        this.mode = mode;
        lblMode.setText(mode + " Supplier");
        if(mode.equals("Add")) {
            lblSupId.setVisible(false);
        }
        else if(mode.equals("Edit")) {
            lblSupId.setVisible(true);
        }
    }

}
