package org.example.petshopdesktop.controllers.dialogcontrollers;

import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
import org.example.petshopdesktop.Validator;
import org.example.petshopdesktop.api.dto.common.DropdownOption;
import org.example.petshopdesktop.api.dto.employee.EmployeeRequest;
import org.example.petshopdesktop.api.dto.employee.EmployeeResponse;
import org.example.petshopdesktop.api.endpoints.DropdownApi;
import org.example.petshopdesktop.api.endpoints.EmployeeApi;
import org.example.petshopdesktop.util.ActivityLogger;
import org.example.petshopdesktop.util.TextFieldFormatSupport;

import java.util.List;

public class StaffEditDialogController {

    @FXML private TextField txtFirstName;
    @FXML private TextField txtLastName;
    @FXML private TextField txtEmail;
    @FXML private TextField txtPhone;
    @FXML private TextField txtUsername;
    @FXML private PasswordField txtPassword;
    @FXML private PasswordField txtPasswordConfirm;
    @FXML private ComboBox<String> cbRole;
    @FXML private ComboBox<String> cbStaffRole;
    @FXML private ComboBox<String> cbActive;
    @FXML private ComboBox<DropdownOption> cbStore;
    @FXML private Label lblError;
    @FXML private Button btnSave;

    private EmployeeResponse employee;
    private Long pendingStoreId = null;

    @FXML
    void initialize() {
        TextFieldFormatSupport.applyPhoneNumberFormat(txtPhone);

        cbRole.setItems(FXCollections.observableArrayList("STAFF", "ADMIN"));
        cbStaffRole.setItems(FXCollections.observableArrayList(
                "STORE_MANAGER", "SALES_ASSOCIATE", "GROOMER", "VETERINARIAN"));
        cbActive.setItems(FXCollections.observableArrayList("Active", "Inactive"));

        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());
            }
        });

        loadStores();
    }

    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("StaffEditDialogController.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;
            }
        }
    }

    public void setEmployee(EmployeeResponse emp) {
        this.employee = emp;
        String fullName = emp.getFullName() != null ? emp.getFullName() : "";
        if (fullName.isEmpty() && emp.getFirstName() != null) {
            fullName = emp.getFirstName() + (emp.getLastName() != null ? " " + emp.getLastName() : "");
        }
        String[] names = splitFullName(fullName);
        txtFirstName.setText(names[0]);
        txtLastName.setText(names[1]);
        txtEmail.setText(emp.getEmail());
        txtPhone.setText(emp.getPhone());
        txtUsername.setText(emp.getUsername());

        if (emp.getRole() != null) cbRole.setValue(emp.getRole());
        if (emp.getStaffRole() != null) cbStaffRole.setValue(emp.getStaffRole());
        cbActive.setValue(Boolean.TRUE.equals(emp.getActive()) ? "Active" : "Inactive");

        pendingStoreId = emp.getPrimaryStoreId();
        applyPendingStore();
    }

    private String[] splitFullName(String fullName) {
        if (fullName == null || fullName.trim().isEmpty()) return new String[]{"", ""};
        String[] parts = fullName.trim().split("\\s+", 2);
        return new String[]{parts.length > 0 ? parts[0] : "", parts.length > 1 ? parts[1] : ""};
    }

    @FXML
    void btnSaveClicked(ActionEvent event) {
        lblError.setText("");
        if (employee == null) {
            lblError.setText("No employee selected.");
            return;
        }

        String firstName = value(txtFirstName);
        String lastName = value(txtLastName);
        String email = value(txtEmail);
        String phone = value(txtPhone);
        String username = value(txtUsername);
        String password = txtPassword.getText() == null ? "" : txtPassword.getText().trim();
        String confirm = txtPasswordConfirm.getText() == null ? "" : txtPasswordConfirm.getText().trim();

        if (firstName.isBlank() || lastName.isBlank()) {
            lblError.setText("First name and last name are required.");
            return;
        }
        if (email.isBlank()) {
            lblError.setText("Email is required.");
            return;
        }
        if (phone.isBlank()) {
            lblError.setText("Phone is required.");
            return;
        }
        String phoneError = Validator.isValidPhoneNumber(phone, "Phone");
        if (!phoneError.isEmpty()) {
            lblError.setText(phoneError.trim());
            return;
        }
        if (username.isBlank()) {
            lblError.setText("Username is required.");
            return;
        }
        if (!password.isEmpty() && password.length() < 6) {
            lblError.setText("Password must be at least 6 characters.");
            return;
        }
        if (!password.equals(confirm)) {
            lblError.setText("Passwords do not match.");
            return;
        }
        if (cbRole.getValue() == null) {
            lblError.setText("Role is required.");
            return;
        }
        if (cbStaffRole.getValue() == null) {
            lblError.setText("Staff role is required.");
            return;
        }
        if (cbStore.getValue() == null) {
            lblError.setText("Primary store is required.");
            return;
        }

        btnSave.setDisable(true);

        String role = cbRole.getValue();
        String staffRole = cbStaffRole.getValue();
        boolean active = "Active".equals(cbActive.getValue());
        Long storeId = cbStore.getValue().getId();

        new Thread(() -> {
            try {
                EmployeeRequest request = new EmployeeRequest();
                request.setUsername(username);
                request.setPassword(password.isEmpty() ? null : password);
                request.setFirstName(firstName);
                request.setLastName(lastName);
                request.setFullName(firstName + " " + lastName);
                request.setEmail(email);
                request.setPhone(phone);
                request.setRole(role);
                request.setStaffRole(staffRole);
                request.setActive(active);
                request.setPrimaryStoreId(storeId);

                EmployeeApi.getInstance().updateEmployee(employee.getId(), request);

                Platform.runLater(this::close);
            } catch (Exception e) {
                ActivityLogger.getInstance().logException("StaffEditDialogController.btnSaveClicked", e, "Updating employee");
                String msg = e.getMessage() == null ? "Could not update employee." : e.getMessage();
                Platform.runLater(() -> {
                    lblError.setText(msg);
                    btnSave.setDisable(false);
                });
            }
        }).start();
    }

    @FXML
    void btnCancelClicked(ActionEvent event) {
        close();
    }

    private void close() {
        Stage stage = (Stage) btnSave.getScene().getWindow();
        stage.close();
    }

    private static String value(TextField tf) {
        return tf.getText() == null ? "" : tf.getText().trim();
    }
}
