# PrintedBook.java

    package com.university.bookstore.model;

    import java.util.regex.Pattern;
    import com.fasterxml.jackson.annotation.JsonCreator;
    import com.fasterxml.jackson.annotation.JsonProperty;
    import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

    /**
     * Represents a physical printed book in the bookstore inventory.
     * Extends Material class to demonstrate inheritance.
     *
     * <p>This class maintains backward compatibility with the original Book class
     * while integrating into the new polymorphic material hierarchy.</p>
     *
     * @author Navid Mohaghegh
     * @version 2.0
     * @since 2024-09-15
     */
    @JsonIgnoreProperties(ignoreUnknown = true)
    public class PrintedBook extends Material {

        private static final Pattern ISBN_13_PATTERN = Pattern.compile("^\\d{13}$");
        private static final Pattern ISBN_10_PATTERN = Pattern.compile("^\\d{9}[\\dX]$");

        private final String isbn;
        private final String author;
        private final int pages;
        private final String publisher;
        private final boolean hardcover;

        /**
         * Creates a new PrintedBook with validation.
         *
         * @param isbn the International Standard Book Number
         * @param title the book title
         * @param author the primary author
         * @param price the price in dollars
         * @param year the publication year
         * @param pages number of pages
         * @param publisher the publishing company
         * @param hardcover true if hardcover, false if paperback
         */
        @JsonCreator
        public PrintedBook(@JsonProperty("id") String isbn,
                           @JsonProperty("title") String title,
                           @JsonProperty("author") String author,
                           @JsonProperty("price") double price,
                           @JsonProperty("year") int year,
                           @JsonProperty("pages") int pages,
                           @JsonProperty("publisher") String publisher,
                           @JsonProperty("hardcover") boolean hardcover) {
            super(validateIsbn(isbn), title, price, year, MaterialType.BOOK);
            this.isbn = this.id;
            this.author = validateStringField(author, "Author");
            this.pages = validatePages(pages);
            this.publisher = validateStringField(publisher, "Publisher");
            this.hardcover = hardcover;
        }

        /**
         * Convenience constructor for backward compatibility.
         */
        public PrintedBook(String isbn, String title, String author, double price, int year) {
            this(isbn, title, author, price, year, 0, "Unknown", false);
        }

        private static String validateIsbn(String isbn) {
            if (isbn == null) {
                throw new NullPointerException("ISBN cannot be null");
            }

            String cleaned = isbn.replaceAll("-", "").trim();

            if (!ISBN_10_PATTERN.matcher(cleaned).matches() &&
                !ISBN_13_PATTERN.matcher(cleaned).matches()) {
                throw new IllegalArgumentException(
                    "ISBN must be 10 or 13 digits. Provided: " + isbn);
            }

            return cleaned;
        }

        private int validatePages(int pages) {
            if (pages < 0) {
                throw new IllegalArgumentException("Pages cannot be negative");
            }
            return pages;
        }

        @Override
        public String getCreator() {
            return author;
        }

        @Override
        public String getDisplayInfo() {
            return String.format("%s by %s (%d, %s) - %d pages, $%.2f",
                title, author, year,
                hardcover ? "Hardcover" : "Paperback",
                pages, price);
        }

        @Override
        public double getDiscountRate() {
            int currentYear = java.time.Year.now().getValue();
            if (year < currentYear - 2) {
                return 0.15;
            }
            return 0.0;
        }

        public String getIsbn() {
            return isbn;
        }

        public String getAuthor() {
            return author;
        }

        public int getPages() {
            return pages;
        }

        public String getPublisher() {
            return publisher;
        }

        public boolean isHardcover() {
            return hardcover;
        }

        /**
         * Calculates estimated reading time based on average reading speed.
         *
         * @param wordsPerMinute reading speed (typical: 200-250)
         * @return estimated hours to read
         */
        public double estimateReadingTime(int wordsPerMinute) {
            if (pages == 0 || wordsPerMinute <= 0) {
                return 0;
            }
            int avgWordsPerPage = 250;
            int totalWords = pages * avgWordsPerPage;
            return totalWords / (double)(wordsPerMinute * 60);
        }

        @Override
        public String toString() {
            return String.format("PrintedBook[ISBN=%s, Title='%s', Author='%s', Price=$%.2f, Year=%d, Pages=%d, %s]",
                isbn, title, author, price, year, pages,
                hardcover ? "Hardcover" : "Paperback");
        }
    }