package org.example.petshopdesktop.controllers.dialogcontrollers;

import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.stage.Stage;
import org.example.petshopdesktop.models.SaleDetail;
import org.example.petshopdesktop.controllers.dialogcontrollers.RefundDialogController;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Modality;
import org.example.petshopdesktop.util.ActivityLogger;
import org.example.petshopdesktop.auth.UserSession;

import java.util.function.Consumer;

import java.text.NumberFormat;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class SaleDetailDialogController {

    @FXML private Label lblSaleId;
    @FXML private Label lblSaleDate;
    @FXML private Label lblEmployee;
    @FXML private Label lblPayment;
    @FXML private Label lblCustomer;
    @FXML private javafx.scene.layout.HBox hbDetailSubtotal;
    @FXML private Label lblDetailSubtotal;
    @FXML private javafx.scene.layout.HBox hbDetailCouponDiscount;
    @FXML private Label lblDetailCouponDiscount;
    @FXML private javafx.scene.layout.HBox hbDetailLoyaltyDiscount;
    @FXML private Label lblDetailLoyaltyDiscountTitle;
    @FXML private Label lblDetailLoyaltyDiscount;
    @FXML private Label lblTotal;
    @FXML private Button btnRefund;
    @FXML private TableView<SaleDetail.SaleDetailItem> tvItems;
    @FXML private TableColumn<SaleDetail.SaleDetailItem, String> colProduct;
    @FXML private TableColumn<SaleDetail.SaleDetailItem, Integer> colQuantity;
    @FXML private TableColumn<SaleDetail.SaleDetailItem, Double> colUnitPrice;
    @FXML private TableColumn<SaleDetail.SaleDetailItem, Double> colLineTotal;

    private final NumberFormat currency = NumberFormat.getCurrencyInstance(Locale.CANADA);
    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
    private Long saleId;
    private Consumer<Long> refundAction;

    @FXML
    public void initialize() {
        tvItems.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
        colProduct.setCellValueFactory(new PropertyValueFactory<>("productName"));
        colQuantity.setCellValueFactory(new PropertyValueFactory<>("quantity"));
        colUnitPrice.setCellValueFactory(new PropertyValueFactory<>("unitPrice"));
        colLineTotal.setCellValueFactory(new PropertyValueFactory<>("total"));

        if (btnRefund != null) {
            boolean isAdmin = UserSession.getInstance().isAdmin();
            btnRefund.setVisible(!isAdmin);
            btnRefund.setManaged(!isAdmin);
        }
    }

    public void displaySaleDetails(SaleDetail sale) {
        saleId = (long) sale.getSaleId();
        lblSaleId.setText(String.valueOf(sale.getSaleId()));
        lblSaleDate.setText(sale.getSaleDate() != null ? sale.getSaleDate().format(DATE_FORMATTER) : "");
        lblEmployee.setText(sale.getEmployeeName() != null ? sale.getEmployeeName() : "");
        lblPayment.setText(sale.getPaymentMethod() != null ? sale.getPaymentMethod() : "");
        lblCustomer.setText(sale.getCustomerName() != null && !sale.getCustomerName().isEmpty() ? sale.getCustomerName() : "-");

        if (!sale.isRefund() && sale.getSubtotalAmount() > 0) {
            hbDetailSubtotal.setVisible(true);
            hbDetailSubtotal.setManaged(true);
            lblDetailSubtotal.setText(currency.format(sale.getSubtotalAmount()));

            if (sale.getCouponDiscountAmount() > 0.001) {
                lblDetailCouponDiscount.setText("-" + currency.format(sale.getCouponDiscountAmount()));
                hbDetailCouponDiscount.setVisible(true);
                hbDetailCouponDiscount.setManaged(true);
            } else {
                hbDetailCouponDiscount.setVisible(false);
                hbDetailCouponDiscount.setManaged(false);
            }

            if (sale.getLoyaltyDiscountAmount() > 0.001) {
                lblDetailLoyaltyDiscount.setText("-" + currency.format(sale.getLoyaltyDiscountAmount()));
                if (sale.getPointsUsed() > 0) {
                    lblDetailLoyaltyDiscountTitle.setText("Loyalty Discount (" + sale.getPointsUsed() + " pts):");
                } else {
                    lblDetailLoyaltyDiscountTitle.setText("Loyalty Discount:");
                }
                hbDetailLoyaltyDiscount.setVisible(true);
                hbDetailLoyaltyDiscount.setManaged(true);
            } else {
                hbDetailLoyaltyDiscount.setVisible(false);
                hbDetailLoyaltyDiscount.setManaged(false);
            }
        } else {
            hbDetailSubtotal.setVisible(false);
            hbDetailSubtotal.setManaged(false);
            hbDetailCouponDiscount.setVisible(false);
            hbDetailCouponDiscount.setManaged(false);
            hbDetailLoyaltyDiscount.setVisible(false);
            hbDetailLoyaltyDiscount.setManaged(false);
        }

        lblTotal.setText(currency.format(sale.getTotalAmount()));
        tvItems.setItems(sale.getItems());
        if (btnRefund != null) {
            boolean isAdmin = UserSession.getInstance().isAdmin();
            if (!isAdmin) {
                btnRefund.setDisable(sale.isRefund());
            }
        }
    }

    public void setSaleId(Long saleId) {
        this.saleId = saleId;
    }

    public void setRefundAction(Consumer<Long> refundAction) {
        this.refundAction = refundAction;
    }

    @FXML
    void btnRefundClicked() {
        if (saleId == null) {
            return;
        }
        if (refundAction != null) {
            refundAction.accept(saleId);
            return;
        }
        try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("/org/example/petshopdesktop/dialogviews/refund-dialog-view.fxml"));
            Stage dialog = new Stage();
            dialog.initOwner(tvItems.getScene().getWindow());
            dialog.initModality(Modality.APPLICATION_MODAL);
            dialog.setTitle("Process Refund");
            dialog.setScene(new Scene(loader.load()));
            RefundDialogController controller = loader.getController();
            controller.prefillSale(saleId);
            dialog.showAndWait();
        } catch (Exception e) {
            ActivityLogger.getInstance().logException("SaleDetailDialogController.btnRefundClicked", e, "Opening refund dialog");
        }
    }

    @FXML
    void btnCloseClicked() {
        Stage stage = (Stage) tvItems.getScene().getWindow();
        stage.close();
    }
}
