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.PasswordField;
import javafx.scene.control.TextField;
import javafx.scene.image.ImageView;
import javafx.stage.Stage;
import org.example.petshopdesktop.Validator;
import org.example.petshopdesktop.api.dto.user.UserRequest;
import org.example.petshopdesktop.api.dto.user.UserResponse;
import org.example.petshopdesktop.api.endpoints.CustomerApi;
import org.example.petshopdesktop.api.endpoints.UserApi;
import org.example.petshopdesktop.auth.UserSession;
import org.example.petshopdesktop.util.ActivityLogger;
import org.example.petshopdesktop.util.DesktopImageSupport;
import org.example.petshopdesktop.util.FilePickerSupport;
import org.example.petshopdesktop.util.TextFieldFormatSupport;

import java.io.File;

public class CustomerEditDialogController {

    @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> cbActive;
    @FXML private TextField txtLoyaltyPoints;
    @FXML private Label lblError;
    @FXML private Button btnSave;

    @FXML private ImageView imgAvatarPreview;
    @FXML private Label lblAvatarStatus;
    @FXML private Button btnChangeAvatar;
    @FXML private Button btnRemoveAvatar;

    private UserResponse customer;
    private File selectedAvatarFile;
    private String currentAvatarUrl;
    private boolean removeAvatarRequested;

    @FXML
    void initialize() {
        TextFieldFormatSupport.applyPhoneNumberFormat(txtPhone);
        cbActive.setItems(FXCollections.observableArrayList("Active", "Inactive"));

        boolean isAdmin = UserSession.getInstance().isAdmin();
        txtLoyaltyPoints.setDisable(!isAdmin);

        btnChangeAvatar.setOnMouseClicked(e -> handleChangeAvatar());
        btnRemoveAvatar.setOnMouseClicked(e -> handleRemoveAvatar());
    }

    public void setCustomer(UserResponse user) {
        this.customer = user;
        String fullName = user.getFullName() == null ? "" : user.getFullName();
        String[] names = splitFullName(fullName);
        txtFirstName.setText(names[0]);
        txtLastName.setText(names[1]);
        txtEmail.setText(user.getEmail());
        txtPhone.setText(user.getPhone());
        txtUsername.setText(user.getUsername());
        cbActive.setValue(Boolean.TRUE.equals(user.getActive()) ? "Active" : "Inactive");
        int pts = user.getLoyaltyPoints() != null ? user.getLoyaltyPoints() : 0;
        txtLoyaltyPoints.setText(String.valueOf(pts));

        currentAvatarUrl = user.getAvatarUrl();
        refreshAvatarPreview();
    }

    private void handleChangeAvatar() {
        File file = FilePickerSupport.pickImageFile(btnSave.getScene().getWindow());
        if (file == null) return;
        selectedAvatarFile = file;
        removeAvatarRequested = false;
        lblAvatarStatus.setText("Selected: " + file.getName());
        DesktopImageSupport.loadImageInto(imgAvatarPreview, file.toURI().toString(), 90, 90);
        btnRemoveAvatar.setDisable(false);
    }

    private void handleRemoveAvatar() {
        selectedAvatarFile = null;
        removeAvatarRequested = true;
        currentAvatarUrl = null;
        refreshAvatarPreview();
    }

    private void applyAvatarChanges(Long userId) throws Exception {
        String previousAvatarUrl = currentAvatarUrl;
        if (removeAvatarRequested) {
            try {
                UserApi.getInstance().deleteUserAvatar(userId);
            } catch (Exception ignored) {
            }
        }
        if (selectedAvatarFile != null) {
            UserApi.getInstance().uploadUserAvatar(userId, selectedAvatarFile.toPath());
            currentAvatarUrl = "/api/v1/users/" + userId + "/avatar/file";
        } else if (removeAvatarRequested) {
            currentAvatarUrl = null;
        }
        DesktopImageSupport.evict(previousAvatarUrl);
        DesktopImageSupport.evict(currentAvatarUrl);
        selectedAvatarFile = null;
        removeAvatarRequested = false;
    }

    private void refreshAvatarPreview() {
        if (imgAvatarPreview == null || lblAvatarStatus == null || btnRemoveAvatar == null) return;
        imgAvatarPreview.setImage(null);
        if (selectedAvatarFile != null) {
            lblAvatarStatus.setText("Selected: " + selectedAvatarFile.getName());
            DesktopImageSupport.loadImageInto(imgAvatarPreview, selectedAvatarFile.toURI().toString(), 90, 90);
            btnRemoveAvatar.setDisable(false);
            return;
        }
        if (currentAvatarUrl != null && !currentAvatarUrl.isBlank()) {
            lblAvatarStatus.setText("Current avatar loaded");
            DesktopImageSupport.loadImageInto(imgAvatarPreview, currentAvatarUrl, 90, 90);
            btnRemoveAvatar.setDisable(false);
            return;
        }
        lblAvatarStatus.setText("No avatar");
        btnRemoveAvatar.setDisable(true);
    }

    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 (customer == null) {
            lblError.setText("No customer 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();
        String loyaltyPointsText = value(txtLoyaltyPoints);

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

        Integer loyaltyPoints = null;
        if (UserSession.getInstance().isAdmin()) {
            if (loyaltyPointsText.isBlank()) {
                lblError.setText("Loyalty points is required.");
                return;
            }
            try {
                loyaltyPoints = Integer.parseInt(loyaltyPointsText);
                if (loyaltyPoints < 0) {
                    lblError.setText("Loyalty points cannot be negative.");
                    return;
                }
            } catch (NumberFormatException e) {
                lblError.setText("Loyalty points must be a valid integer.");
                return;
            }
        }

        btnSave.setDisable(true);

        boolean active = "Active".equals(cbActive.getValue());
        Integer finalLoyaltyPoints = loyaltyPoints;

        new Thread(() -> {
            try {
                UserRequest request = new UserRequest();
                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(customer.getRole());
                request.setActive(active);
                if (finalLoyaltyPoints != null) request.setLoyaltyPoints(finalLoyaltyPoints);

                CustomerApi.getInstance().updateCustomer(customer.getId(), request);
                applyAvatarChanges(customer.getId());

                Platform.runLater(this::close);
            } catch (Exception e) {
                ActivityLogger.getInstance().logException("CustomerEditDialogController.btnSaveClicked", e, "Updating customer");
                String msg = e.getMessage() == null ? "Could not update customer." : 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();
    }
}
