# DiscountHandler.java

    package com.university.bookstore.chain;

    /**
     * Abstract base class for discount approval handlers in the Chain of Responsibility pattern.
     * Defines the interface for handling discount requests and managing the chain.
     *
     * <p>This class provides the basic structure for the chain of responsibility,
     * allowing handlers to either process requests or pass them to the next handler.</p>
     *
     * @author Navid Mohaghegh
     * @version 3.0
     * @since 2024-09-15
     */
    public abstract class DiscountHandler {

        protected DiscountHandler nextHandler;

        /**
         * Sets the next handler in the chain.
         *
         * @param nextHandler the next handler
         */
        public void setNext(DiscountHandler nextHandler) {
            this.nextHandler = nextHandler;
        }

        /**
         * Gets the next handler in the chain.
         *
         * @return the next handler
         */
        public DiscountHandler getNext() {
            return nextHandler;
        }

        /**
         * Handles a discount request.
         * Subclasses must implement this method to define their approval logic.
         *
         * @param request the discount request to handle
         */
        public abstract void handleRequest(DiscountRequest request);

        /**
         * Passes the request to the next handler in the chain.
         *
         * @param request the request to pass
         */
        protected void passToNext(DiscountRequest request) {
            if (nextHandler != null) {
                nextHandler.handleRequest(request);
            } else {
                // End of chain - reject if not approved
                if (!request.isApproved()) {
                    request.setRejectionReason("No handler could approve this discount");
                }
            }
        }

        /**
         * Gets the name of this handler for identification purposes.
         *
         * @return the handler name
         */
        public abstract String getHandlerName();

        /**
         * Gets the maximum discount this handler can approve.
         *
         * @return the maximum discount rate (0.0 to 1.0)
         */
        public abstract double getMaxDiscount();

        /**
         * Checks if this handler can approve the given discount amount.
         *
         * @param discount the discount rate to check
         * @return true if this handler can approve the discount
         */
        public boolean canApprove(double discount) {
            return discount <= getMaxDiscount();
        }

        /**
         * Gets the chain length from this handler to the end.
         *
         * @return the chain length
         */
        public int getChainLength() {
            int length = 1;
            DiscountHandler current = nextHandler;
            while (current != null) {
                length++;
                current = current.getNext();
            }
            return length;
        }

        /**
         * Gets information about this handler and the chain.
         *
         * @return handler information
         */
        public String getHandlerInfo() {
            return String.format("%s[MaxDiscount=%.1f%%, ChainLength=%d]",
                getHandlerName(), getMaxDiscount() * 100, getChainLength());
        }

        @Override
        public String toString() {
            return getHandlerInfo();
        }
    }