package org.example.petshopdesktop.controllers.dialogcontrollers;

import javafx.collections.FXCollections;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.input.MouseEvent;
import javafx.stage.Stage;
import org.example.petshopdesktop.api.dto.coupon.CouponRequest;
import org.example.petshopdesktop.api.dto.coupon.CouponResponse;
import org.example.petshopdesktop.api.endpoints.CouponApi;
import org.example.petshopdesktop.util.ActivityLogger;

import java.math.BigDecimal;
import java.time.LocalDate;

public class CouponDialogController {

    @FXML private Button btnSave;
    @FXML private Button btnCancel;
    @FXML private Label lblMode;
    @FXML private Label lblCouponId;
    @FXML private TextField txtCode;
    @FXML private ComboBox<String> cbDiscountType;
    @FXML private TextField txtDiscountValue;
    @FXML private TextField txtMinOrder;
    @FXML private DatePicker dpStartsAt;
    @FXML private DatePicker dpEndsAt;
    @FXML private TextField txtUsageLimit;
    @FXML private CheckBox chkActive;

    private String mode;
    private Long couponId;

    @FXML
    void initialize() {
        cbDiscountType.setItems(FXCollections.observableArrayList("FIXED", "PERCENT"));

        dpEndsAt.setDisable(true);

        dpStartsAt.setDayCellFactory(picker -> new javafx.scene.control.DateCell() {
            @Override
            public void updateItem(LocalDate item, boolean empty) {
                super.updateItem(item, empty);
                setDisable(empty || item.isBefore(LocalDate.now()));
            }
        });

        dpStartsAt.valueProperty().addListener((obs, oldVal, newVal) -> {
            if (newVal == null) {
                dpEndsAt.setValue(null);
                dpEndsAt.setDisable(true);
            } else {
                dpEndsAt.setDisable(false);
                dpEndsAt.setDayCellFactory(picker -> new javafx.scene.control.DateCell() {
                    @Override
                    public void updateItem(LocalDate item, boolean empty) {
                        super.updateItem(item, empty);
                        setDisable(empty || !item.isAfter(newVal));
                    }
                });
                if (dpEndsAt.getValue() != null && !dpEndsAt.getValue().isAfter(newVal)) {
                    dpEndsAt.setValue(null);
                }
            }
        });

        btnSave.setOnMouseClicked(this::handleSave);
        btnCancel.setOnMouseClicked(this::handleCancel);
    }

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

    public void displayCouponDetails(CouponResponse coupon) {
        if (coupon == null) return;
        couponId = coupon.getCouponId();
        lblCouponId.setText("ID: " + couponId);
        txtCode.setText(coupon.getCouponCode() != null ? coupon.getCouponCode() : "");
        cbDiscountType.setValue(coupon.getDiscountType());
        txtDiscountValue.setText(coupon.getDiscountValue() != null ? coupon.getDiscountValue().toPlainString() : "");
        txtMinOrder.setText(coupon.getMinOrderAmount() != null ? coupon.getMinOrderAmount().toPlainString() : "");
        txtUsageLimit.setText(coupon.getUsageLimit() != null ? coupon.getUsageLimit().toString() : "");
        chkActive.setSelected(Boolean.TRUE.equals(coupon.getActive()));
        if (coupon.getStartsAt() != null && coupon.getStartsAt().length() >= 10) {
            dpStartsAt.setValue(LocalDate.parse(coupon.getStartsAt().substring(0, 10)));
        }
        if (coupon.getEndsAt() != null && coupon.getEndsAt().length() >= 10 && dpStartsAt.getValue() != null) {
            dpEndsAt.setValue(LocalDate.parse(coupon.getEndsAt().substring(0, 10)));
        }
    }

    private void handleSave(MouseEvent event) {
        String errorMsg = "";

        if (txtCode.getText() == null || txtCode.getText().trim().isEmpty()) {
            errorMsg += "Coupon Code is required\n";
        }
        if (cbDiscountType.getValue() == null) {
            errorMsg += "Discount Type is required\n";
        }
        if (txtDiscountValue.getText() == null || txtDiscountValue.getText().trim().isEmpty()) {
            errorMsg += "Discount Value is required\n";
        } else {
            try {
                BigDecimal val = new BigDecimal(txtDiscountValue.getText().trim());
                if (val.compareTo(BigDecimal.ZERO) <= 0) {
                    errorMsg += "Discount Value must be greater than 0\n";
                }
            } catch (NumberFormatException e) {
                errorMsg += "Discount Value must be a valid number\n";
            }
        }
        if (!txtMinOrder.getText().trim().isEmpty()) {
            try {
                BigDecimal min = new BigDecimal(txtMinOrder.getText().trim());
                if (min.compareTo(BigDecimal.ZERO) < 0) {
                    errorMsg += "Min Order Amount must be 0 or greater\n";
                }
            } catch (NumberFormatException e) {
                errorMsg += "Min Order Amount must be a valid number\n";
            }
        }
        if (!txtUsageLimit.getText().trim().isEmpty()) {
            try {
                int limit = Integer.parseInt(txtUsageLimit.getText().trim());
                if (limit <= 0) {
                    errorMsg += "Usage Limit must be a positive number\n";
                }
            } catch (NumberFormatException e) {
                errorMsg += "Usage Limit must be a valid integer\n";
            }
        }
        if (dpStartsAt.getValue() != null && dpEndsAt.getValue() != null
                && !dpEndsAt.getValue().isAfter(dpStartsAt.getValue())) {
            errorMsg += "Ends At must be after Starts At\n";
        }

        if (!errorMsg.isEmpty()) {
            Alert alert = new Alert(Alert.AlertType.ERROR);
            alert.setHeaderText("Input Error");
            alert.setContentText(errorMsg);
            alert.showAndWait();
            return;
        }

        CouponRequest request = buildRequest();
        try {
            if ("Add".equals(mode)) {
                CouponApi.getInstance().createCoupon(request);
            } else {
                CouponApi.getInstance().updateCoupon(couponId, request);
            }
            Alert alert = new Alert(Alert.AlertType.INFORMATION);
            alert.setHeaderText("Saved");
            alert.setContentText(mode + " succeeded");
            alert.showAndWait();
            closeStage(event);
        } catch (Exception e) {
            ActivityLogger.getInstance().logException("CouponDialogController.handleSave", e, mode + " coupon");
            Alert alert = new Alert(Alert.AlertType.ERROR);
            alert.setHeaderText("Operation Error");
            alert.setContentText(mode + " failed: " + e.getMessage());
            alert.showAndWait();
        }
    }

    private void handleCancel(MouseEvent event) {
        closeStage(event);
    }

    private CouponRequest buildRequest() {
        CouponRequest request = new CouponRequest();
        request.setCouponCode(txtCode.getText().trim().toUpperCase());
        request.setDiscountType(cbDiscountType.getValue());
        request.setDiscountValue(new BigDecimal(txtDiscountValue.getText().trim()));
        request.setActive(chkActive.isSelected());

        if (!txtMinOrder.getText().trim().isEmpty()) {
            request.setMinOrderAmount(new BigDecimal(txtMinOrder.getText().trim()));
        }
        if (!txtUsageLimit.getText().trim().isEmpty()) {
            request.setUsageLimit(Integer.parseInt(txtUsageLimit.getText().trim()));
        }
        if (dpStartsAt.getValue() != null) {
            request.setStartsAt(dpStartsAt.getValue().toString() + "T00:00:00");
        }
        if (dpEndsAt.getValue() != null) {
            request.setEndsAt(dpEndsAt.getValue().toString() + "T23:59:59");
        }
        return request;
    }

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