package cpsc4620;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.SQLException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.regex.Pattern;

/**
 * Main program class responsible for user-facing I/O operations presented as a program menu.
 */
public class Menu {

	// BufferedReader for use throughout program
	public static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

	// Global toppings list so that topping tracking works properly across multiple pizzas
	private static ArrayList<Topping> toppings;

	/**
	 * Main function which serves as the program's entry point, presents the user with the program menu, and
	 * takes in menu choice input to handle appropriately.
	 *
	 * @param args Program arguments
	 * @throws SQLException
	 * @throws IOException
	 */
	public static void main(String[] args) throws SQLException, IOException {

		// Re-initialize BufferedReader
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

		// Welcome message
		System.out.println("Welcome to Pizzas-R-Us!");

		// Present program menu
		PrintMenu();
		// Take in user menu selection
		int menuOption = Integer.parseInt(reader.readLine());

		// Loop until the user enters 9
		while (menuOption != 9) {

			switch (menuOption) {

				// Enter order
				case 1:
					EnterOrder();
					break;

				// View customers
				case 2:
					viewCustomers();
					break;

				// Enter customer
				case 3:
					EnterCustomer();
					break;

				// View orders
				case 4:
					// open/closed/date
					ViewOrders();
					break;

				// Mark order as complete
				case 5:
					MarkOrderAsComplete();
					break;

				// View inventory levels
				case 6:
					ViewInventoryLevels();
					break;

				// Add to inventory
				case 7:
					AddInventory();
					break;

				// View reports
				case 8:
					PrintReports();
					break;

				// Print error message for unrecognized input
				default:
					System.out.println("Menu option not recognized. Please try again.");

			}

			PrintMenu();
			menuOption = Integer.parseInt(reader.readLine());

		}

	}

	/**
	 * Helper function which gets user input for order type.
	 *
	 * @return Normalized order type
	 * @throws IOException
	 */
	public static String getOrderType() throws IOException {

		// Re-initialize BufferedReader
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

		// Prompt user for order type
		System.out.println("Is this order for: \n1.) Dine-in\n2.) Pick-up\n3.) Delivery\nEnter the number of your choice:");
		// Get user input
		String orderType = reader.readLine();

		// Loop to handle invalid input
		while (Integer.parseInt(orderType) < 1 || Integer.parseInt(orderType) > 3) {

			// Print error and prompt user again
			System.out.println("ERROR: I don't understand your input for: Is this order for: \n1.) Dine-in\n2.) Pick-up\n3.) Delivery");
			// Get user input
			orderType = reader.readLine();

		}

		// Normalize orderType based on user input
		if (Integer.parseInt(orderType) == 1) { // dine-in order

			orderType = DBNinja.dine_in;

		} else if (Integer.parseInt(orderType) == 2) { // pickup order

			orderType = DBNinja.pickup;

		} else { // delivery

			orderType = DBNinja.delivery;

		}

		return orderType;

	}

	/**
	 * Function which prompts user for details about a new order.
	 *
	 * @throws SQLException
	 * @throws IOException
	 */
	public static void EnterOrder() throws SQLException, IOException {

		// Re-initialize BufferedReader for I/O
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

		// Re-initialize global toppings list with latest DB data
		toppings = DBNinja.getToppingList();

		// Create an Order object to be initialized based on user input
		Order order;
		// Call helper function getOrderType() to get normalized user input
		String orderType = getOrderType();

		// If the order is a dine-in order
		if (orderType.equals(DBNinja.dine_in)) {

			// Prompt user for the dine-in table number
			System.out.println("What is the table number for this order?");
			// Get user input
			int tableNum = Integer.parseInt(reader.readLine());

			// Initialize order as dine-in order with default values which will be set properly later
			order = new DineinOrder(0, 0, "", 0.0, 0.0, 0, tableNum);
			order.setOrderType(DBNinja.dine_in);

			// If the order is a pickup order or delivery order
		} else {

			// Prompt user about customer
			System.out.println("Is this order for an existing customer? Answer y/n: ");

			// Get user input
			char customerOption = reader.readLine().toLowerCase().charAt(0);
			// Validate user input
			while (customerOption != 'y' && customerOption != 'n') {

				// Print error message and get user input again
				System.out.println("ERROR: I don't understand your input for: Is this order an existing customer?");
				customerOption = reader.readLine().toLowerCase().charAt(0);

			}

			// Variable to hold the CustomerID for the order
			int customerID;
			// If the order is for an existing customer
			if (customerOption == 'y') {

				// Print list of customers
				System.out.println("Here's a list of the current customers: ");
				viewCustomers();

				// Prompt user for customer selection and get input
				System.out.println("Which customer is this order for? Enter ID Number:");
				customerID = Integer.parseInt(reader.readLine());
				// Validate user input
				while (customerID < 1 || customerID > DBNinja.getCustomerList().size()) {

					// Print error and get input again
					System.out.println("Customer selection " + customerID + " is not valid. Please try again.");
					customerID = Integer.parseInt(reader.readLine());

				}

				// If the order is for a new customer
			} else {

				// Enter new customer
				EnterCustomer();

				// Get the CustomerID of the newly-added customer
				customerID = DBNinja.getLatestCustomerID();

			}

			// Initialize order according to pickup or delivery with default values which will be set properly later
			if (orderType.equals(DBNinja.pickup)) { // pickup

				order = new PickupOrder(0, customerID, "", 0.0, 0.0, 0, 0);
				order.setOrderType(DBNinja.pickup);

			} else { // delivery

				order = new DeliveryOrder(0, customerID, "", 0.0, 0.0, 0, "");
				order.setOrderType(DBNinja.delivery);

				// While we're here, go ahead and get delivery address details
				System.out.println("What is the House/Apt Number for this order? (e.g., 111)");
				String house = reader.readLine();
				// Validate input
				while (!Pattern.compile("\\d+").matcher(house.trim()).matches()) {

					// Print error message and get input again
					System.out.println("I don't understand that input. Please try again using all numbers (e.g., 111).");
					house = reader.readLine();

				}
				int houseNum = Integer.parseInt(house);
				System.out.println("What is the Street for this order? (e.g., Smile Street)");
				String street = reader.readLine().trim();
				System.out.println("What is the City for this order? (e.g., Greenville)");
				String city = reader.readLine().trim();
				System.out.println("What is the State for this order? (e.g., SC)");
				String state = reader.readLine().toUpperCase();
				// Validate input
				while (!Pattern.compile("[A-Z]{2}").matcher(state.trim()).matches()) {

					// Print error message and get input again
					System.out.println("I don't understand that input. Please enter the state's two-letter abbreviation (e.g., SC).");
					state = reader.readLine().toUpperCase();

				}
				System.out.println("What is the Zip Code for this order? (e.g., 20605)");
				String zip = reader.readLine();
				// Validate input
				while (!Pattern.compile("\\d{5}").matcher(zip.trim()).matches()) {

					// Print error message and get input again
					System.out.println("I don't understand that input. Please enter the 5-digit zip code (e.g., 20605).");
					zip = reader.readLine();

				}

				// Update delivery address
				((DeliveryOrder) order).setAddress(houseNum + " " + street + "\n" + city + "\n" + state + "\n" + zip);
				// Update address for associated customer
				DBNinja.updateCustomerAddress(customerID, houseNum + " " + street, city, state, zip);

			}

		}

		// Prompt user to start building pizzas
		System.out.println("Let's build a pizza!");
		int pizzaContinueOption;
		// Loop at least once and then until user enters -1 to stop building pizzas
		do {

			order.addPizza(buildPizza(0)); // Use default OrderID 0 since buildPizza does not use it

			System.out.println("Enter -1 to stop adding pizzas...Enter anything else to continue adding pizzas to the order.");
			pizzaContinueOption = Integer.parseInt(reader.readLine());

		} while (pizzaContinueOption != -1);

		// Update order customer price and business price
		for (Pizza pizza : order.getPizzaList()) {

			order.setBusPrice(order.getBusPrice() + pizza.getBusPrice());
			order.setCustPrice(order.getCustPrice() + pizza.getCustPrice());

		}

		// Prompt user for order discounts and get input
		System.out.println("Do you want to add discounts to this order? Enter y/n?");
		char orderDiscountChoice = reader.readLine().toLowerCase().charAt(0);
		// Validate input
		while (orderDiscountChoice != 'y' && orderDiscountChoice != 'n') {

			// Print error message and get input again
			System.out.println("Invalid choice. Please try again.");
			orderDiscountChoice = reader.readLine().toLowerCase().charAt(0);

		}

		// If user wants to add order discounts
		if (orderDiscountChoice == 'y') {

			while (true) {

				// Get list of discounts
				ArrayList<Discount> discounts = DBNinja.getDiscountList();

				// Print order discounts
				DBNinja.printDiscounts(discounts);

				// Prompt user for discount selection and get input
				System.out.println("Which Order Discount do you want to add? Enter the DiscountID. Enter -1 to stop adding Discounts: ");
				int discountID = Integer.parseInt(reader.readLine());
				// Validate input
				while (discountID != -1 && (discountID < 1 || discountID > discounts.size())) {

					// Print error message and get input again
					System.out.println("Invalid selection. Please try again.");
					discountID = Integer.parseInt(reader.readLine());

				}

				// If the user entered -1, break loop early
				if (discountID == -1) {

					break;

				}

				// Make sure order discount has not already been applied
				if (order.getDiscountList().contains(discounts.get(discountID - 1))) { // discount already applied

					// Print error message
					System.out.println("Order discount already applied.");

				} else if (!discounts.get(discountID - 1).isPercent()) { // discount is not an order discount

					System.out.println("Discount is not valid for orders.");

				} else { // discount not yet applied

					// Apply the discount
					order.addDiscount(discounts.get(discountID - 1));

				}

			}

		}

		// Get the current timestamp
		LocalDateTime now = LocalDateTime.now();
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
		order.setDate(now.format(formatter));

		// Add order
		DBNinja.addOrder(order);

		System.out.println("Finished adding order...Returning to menu...");

	}

	/**
	 * Function which simply prints all the customers from the database.
	 *
	 * @throws SQLException
	 * @throws IOException
	 */
	public static void viewCustomers() throws SQLException, IOException {

		// Use existing function to get an ArrayList of Customer objects
		ArrayList<Customer> customers = DBNinja.getCustomerList();

		// Loop through customers
		for (Customer customer : customers) {

			System.out.println(customer.toString());

		}
		
	}

	/**
	 * Function which prompts the user for information about a new customer and adds the
	 * customer to the database.
	 *
	 * @throws SQLException
	 * @throws IOException
	 */
	public static void EnterCustomer() throws SQLException, IOException {

		// Re-initialize BufferedReader for I/O
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

		// Prompt user for customer name
		System.out.println("What is this customer's name (first <space> last)");
		String name = reader.readLine();
		// Validate input
		while (!Pattern.compile("\\w+ \\w+").matcher(name.trim()).matches()) {

			// Print error message and get input again
			System.out.println("I don't understand that input. Please try again using format (first <space> last).");
			name = reader.readLine();

		}
		String[] customerName = name.split(" ");

		// Prompt user for customer phone
		System.out.println("What is this customer's phone number (##########) (No dash/space)");
		String customerPhone = reader.readLine();
		// Validate input
		while (!Pattern.compile("\\d{10}").matcher(customerPhone.trim()).matches()) {

			// Print error message and get input again
			System.out.println("I don't understand that input. Please try again using format (##########) (No dash/space).");
			customerPhone = reader.readLine();

		}

		// Create new Customer object
		Customer customer = new Customer(0, customerName[0], customerName[1], customerPhone);
		// Add new Customer object to database
		DBNinja.addCustomer(customer);

	}

	/**
	 * Function which presents the order history based on user's requirements.
	 *
	 * @throws SQLException
	 * @throws IOException
	 */
	public static void ViewOrders() throws SQLException, IOException {

		// Re-initialize BufferedReader for I/O
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

		// Prompt user and get input
		System.out.println("Would you like to:\n(a) display all orders [open or closed]\n(b) display all open orders\n(c) display all completed [closed] orders\n(d) display orders since a specific date");
		char choice = reader.readLine().toLowerCase().charAt(0);
		// Validate input and return to menu if not recognized
		if (choice != 'a' && choice != 'b' && choice != 'c' && choice != 'd') {

			System.out.println("I don't understand that input, returning to menu");
			return;

		}

		ArrayList<Order> orders;
		// Determine what to do based on input
		if (choice == 'a') { // display all orders

			// Get list of all orders
			orders = DBNinja.getOrders(false);

		} else if (choice == 'b') { // display open orders

			// Get list of all open orders
			orders = DBNinja.getOrders(true);

		} else if (choice == 'c') { // display closed orders

			// Get list of all orders
			orders = DBNinja.getOrders(false);

			// Create a list of orders to remove
			ArrayList<Order> toRemove = new ArrayList<>();

			// Loop through orders and add open orders to list of order to be removed
			for (Order order : orders) {

				if (order.getIsComplete() == 0) {

					toRemove.add(order);

				}

			}

			// Remove orders
			orders.removeAll(toRemove);

		} else { // display orders since date

			// Get list of all orders
			orders = DBNinja.getOrders(false);

			// Prompt for user input for date restriction and get input
			System.out.println("What is the date you want to restrict by? (FORMAT= YYYY-MM-DD)");
			String date = reader.readLine();
			// Validate input
			while (!Pattern.compile("\\d{4}-\\d{2}-\\d{2}").matcher(date.trim()).matches()) {

				// Print error message and get input again
				System.out.println("I don't understand that date. Please try again with format YYYY-MM-DD.");
				date = reader.readLine();

			}

			// Create a list of orders to remove
			ArrayList<Order> toRemove = new ArrayList<>();

			// Loop through orders and add orders before the specified date to the list to be removed
			for (Order order : orders) {

				// Parse the date string into a LocalDate object
				LocalDate lDate = LocalDate.parse(date);

				if (!DBNinja.checkDate(lDate.getYear(), lDate.getMonthValue(), lDate.getDayOfMonth(), order.getDate())) {

					toRemove.add(order);

				}

			}

			// Remove orders
			orders.removeAll(toRemove);

		}

		// Make sure there are orders to print
		if (orders.size() != 0) {

			// Print orders
			DBNinja.printOrders(orders);

		} else {

			// Print error message and return early
			System.out.println("No orders to display, returning to menu.");
			return;

		}

		// Prompt user for order choice and get input
		System.out.println("Which order would you like to see in detail? Enter the number (-1 to exit): ");
		int orderChoice = Integer.parseInt(reader.readLine());
		// Validate input
		while (orderChoice != -1 && (orderChoice < 0 || !DBNinja.orderExists(orders, orderChoice))) {

			// Print error message and get input again
			System.out.println("Incorrect entry, not an option. Please try again.");
			orderChoice = Integer.parseInt(reader.readLine());

		}

		// If user entered -1, return early
		if (orderChoice == -1) {

			return;

		}

		// Get the Order object by OrderID
		Order order = DBNinja.getOrderByID(orderChoice);

		// Print order details
		System.out.println(order.toString());
		// Check if there are order discounts
		if (order.getDiscountList().size() != 0) { // there are order discounts

			// Loop through discounts and print
			for (Discount discount : order.getDiscountList()) {

				System.out.println(discount.toString());

			}

		} else { // there are no order discounts

			System.out.println("NO ORDER DISCOUNTS");

		}
		// Loop through order pizzas
		for (Pizza pizza : order.getPizzaList()) {

			System.out.println(pizza.toString());

			// Check if there are pizza discounts
			if (pizza.getDiscounts().size() != 0) { // there are pizza discounts

				// Loop through discounts and print
				for (Discount discount : pizza.getDiscounts()) {

					System.out.println(discount.toString());

				}

			} else { // there are no pizza discounts

				System.out.println("NO PIZZA DISCOUNTS");

			}

		}

	}

	/**
	 * Function which marks the order of the user's choice as complete.
	 *
	 * @throws SQLException
	 * @throws IOException
	 */
	public static void MarkOrderAsComplete() throws SQLException, IOException {

		// Re-initialize BufferedReader for I/O
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

		// Get the list of open orders
		ArrayList<Order> orders = DBNinja.getOrders(true);

		// If there are no open orders
		if (orders.size() == 0) {

			System.out.println("There are no open orders currently... returning to menu...");
			return;

		} else {

			// Print list
			DBNinja.printOrders(orders);

		}

		// Prompt user for order selection and get input
		System.out.println("Which order would you like mark as complete? Enter the OrderID: ");
		int orderChoice = Integer.parseInt(reader.readLine());
		// Validate input
		while (orderChoice < 0 || !DBNinja.orderExists(orders, orderChoice)) {

			// Print error message and get input again
			System.out.println("Incorrect entry, not an option");
			orderChoice = Integer.parseInt(reader.readLine());

		}

		// Complete order
		DBNinja.completeOrder(DBNinja.getOrderByID(orderChoice));

	}

	/**
	 * Function which prints the inventory levels of each topping in alphabetical order according to
	 * ToppingName.
	 *
	 * @throws SQLException
	 * @throws IOException
	 */
	public static void ViewInventoryLevels() throws SQLException, IOException {

		DBNinja.printInventory();

	}

	/**
	 * Function which prompts the user for the topping they want to update and an amount, then
	 * adds the specified inventory amount to that topping.
	 *
	 * @throws SQLException
	 * @throws IOException
	 */
	public static void AddInventory() throws SQLException, IOException {

		// Re-initialize BufferedReader for I/O
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

		// Get the toppings list and print it
		ArrayList<Topping> toppings = DBNinja.getToppingList();
		DBNinja.printInventoryLevels(toppings);

		// Prompt user and get input
		System.out.println("Which topping do you want to add inventory to? Enter the number: ");
		int toppingChoice = Integer.parseInt(reader.readLine());
		// Validate input
		while (toppingChoice < 1 || toppingChoice > toppings.size()) {

			// Print error message and get input again
			System.out.println("Incorrect entry, not an option");
			toppingChoice = Integer.parseInt(reader.readLine());

		}

		// Prompt user and get input
		System.out.println("How many units would you like to add? ");
		double numToAdd = Double.parseDouble(reader.readLine());

		// Use DBNinja function to add to inventory
		DBNinja.addToInventory(DBNinja.getToppingByID(toppings, toppingChoice), numToAdd);

	}

	/**
	 * Function which prompts the user for the details required to build a pizza.
	 *
	 * @param orderID OrderID associated with pizza (unused)
	 * @return Completed Pizza object
	 * @throws SQLException
	 * @throws IOException
	 */
	public static Pizza buildPizza(int orderID) throws SQLException, IOException {

		// Re-initialize BufferedReader
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

		String[] pizzaSizes = {DBNinja.size_s, DBNinja.size_m, DBNinja.size_l, DBNinja.size_xl};
		// Prompt user for pizza size
		System.out.println("What size is the pizza?");
		System.out.println("1."+DBNinja.size_s);
		System.out.println("2."+DBNinja.size_m);
		System.out.println("3."+DBNinja.size_l);
		System.out.println("4."+DBNinja.size_xl);
		System.out.println("Enter the corresponding number: ");
		// Get user input
		int pizzaSizeOption = Integer.parseInt(reader.readLine());
		// Validate input
		while (pizzaSizeOption < 1 || pizzaSizeOption > 4) {

			// Print error message and get input again
			System.out.println("Invalid input for pizza size. Please try again.");
			pizzaSizeOption = Integer.parseInt(reader.readLine());

		}

		String[] pizzaCrustTypes = {DBNinja.crust_thin, DBNinja.crust_orig, DBNinja.crust_pan, DBNinja.crust_gf};
		// Prompt user for pizza crust type
		System.out.println("What crust for this pizza?");
		System.out.println("1."+DBNinja.crust_thin);
		System.out.println("2."+DBNinja.crust_orig);
		System.out.println("3."+DBNinja.crust_pan);
		System.out.println("4."+DBNinja.crust_gf);
		System.out.println("Enter the corresponding number: ");
		// Get user input
		int pizzaCrustOption = Integer.parseInt(reader.readLine());
		// Validate input
		while (pizzaCrustOption < 1 || pizzaCrustOption > 4) {

			// Print error message and get input again
			System.out.println("Invalid input for pizza crust type. Please try again.");
			pizzaCrustOption = Integer.parseInt(reader.readLine());

		}

		// Get pizza base price and base cost
		double basePrice = DBNinja.getBaseCustPrice(pizzaSizes[pizzaSizeOption - 1], pizzaCrustTypes[pizzaCrustOption - 1]);
		double baseCost = DBNinja.getBaseBusPrice(pizzaSizes[pizzaSizeOption - 1], pizzaCrustTypes[pizzaCrustOption - 1]);
		// Create Pizza object
		Pizza pizza = new Pizza(0, pizzaSizes[pizzaSizeOption - 1], pizzaCrustTypes[pizzaCrustOption - 1], orderID, "not ready", "", basePrice, baseCost);

		// Loop to add toppings and continue until user enters -1
		while (true) {

			// Print available toppings
			System.out.println("Available Toppings:");
			DBNinja.printInventoryLevels(toppings);

			// Prompt for and get user input
			System.out.println("Which topping do you want to add? Enter the TopID. Enter -1 to stop adding toppings: ");
			int toppingID = Integer.parseInt(reader.readLine());
			// Validate input
			while (toppingID != -1 && (toppingID < 1 || toppingID > toppings.size())) {

				// Print error message and get input again
				System.out.println("Invalid topping selection. Please try again.");
				toppingID = Integer.parseInt(reader.readLine());

			}

			// If toppingID is -1, break loop early
			if (toppingID == -1) {

				break;

			}

			// Prompt user for extra topping and get input
			System.out.println("Do you want to add extra topping? Enter y/n");
			char extraToppingChoice = reader.readLine().toLowerCase().charAt(0);
			// Validate input
			while (extraToppingChoice != 'y' && extraToppingChoice != 'n') {

				// Print error message and get input again
				System.out.println("Invalid choice. Please try again.");
				extraToppingChoice = reader.readLine().toLowerCase().charAt(0);

			}

			// Get topping by ID
			Topping topping = DBNinja.getToppingByID(toppings, toppingID);
			// Make sure topping has not already been added
			if (pizza.getToppings().contains(topping)) { // if it has already been added

				System.out.println("Topping already added to pizza.");

			} else { // if it has not already been added

				// Make sure there is enough of the topping to add it
				if (topping.getCurINVT() - topping.getVarAMT(pizzaSizes[pizzaSizeOption - 1], extraToppingChoice == 'y') >= 0) { // if there is enough

					// Add topping to pizza
					pizza.addToppings(topping, extraToppingChoice == 'y');
					// Add extra topping choice to tracking array within pizza object
					pizza.modifyDoubledArray(toppingID - 1, extraToppingChoice == 'y');

					// Subtract required inventory from topping object
					topping.setCurINVT(topping.getCurINVT() - topping.getVarAMT(pizzaSizes[pizzaSizeOption - 1], extraToppingChoice == 'y'));

				} else { // if there isn't enough

					// Print error message
					System.out.println("We don't have enough of that topping to add it...");

				}

			}

		}

		// Prompt user about pizza discounts and get input
		System.out.println("Do you want to add discounts to this Pizza? Enter y/n?");
		char discountChoice = reader.readLine().toLowerCase().charAt(0);
		// Validate input
		while (discountChoice != 'y' && discountChoice != 'n') {

			// Print error message and get input again
			System.out.println("Invalid choice. Please try again.");
			discountChoice = reader.readLine().toLowerCase().charAt(0);

		}

		// If user wants to add pizza discounts
		if (discountChoice == 'y') {

			// Loop to add discounts until user enters -1
			while (true) {

				// Get the list of discounts as usable Discount objects
				ArrayList<Discount> discounts = DBNinja.getDiscountList();

				// Print available discounts
				DBNinja.printDiscounts(discounts);

				// Prompt for and get user input
				System.out.println("Which Pizza Discount do you want to add? Enter the DiscountID. Enter -1 to stop adding Discounts: ");
				int discountID = Integer.parseInt(reader.readLine());
				// Validate input
				while (discountID != -1 && (discountID < 1 || discountID > discounts.size())) {

					// Print error message and get input again
					System.out.println("Invalid discount selection. Please try again.");
					discountID = Integer.parseInt(reader.readLine());

				}

				// If discountID is -1, break loop early
				if (discountID == -1) {

					break;

				}

				// Make sure discount has not already been added and is valid
				if (pizza.getDiscounts().contains(discounts.get(discountID - 1))) { // if it has already been added

					System.out.println("Discount already added to pizza.");

				} else if (discounts.get(discountID - 1).isPercent()) { // if the discount is not a pizza discount

					System.out.println("Discount is not valid for individual pizzas.");

				} else { // if it has not already been added

					// Add discount to pizza
					pizza.addDiscounts(discounts.get(discountID - 1));

				}

			}

		}

		return pizza;

	}

	/**
	 * Function which asks the user which report they want to see and prints the appropriate report.
	 *
	 * @throws SQLException
	 * @throws NumberFormatException
	 * @throws IOException
	 */
	public static void PrintReports() throws SQLException, NumberFormatException, IOException {

		// Initialize BufferedReader for I/O
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

		// Prompt user for input
		System.out.println("Which report do you wish to print? Enter\n(a) ToppingPopularity\n(b) ProfitByPizza\n(c) ProfitByOrderType:");
		// Read user input as character
		char reportOption = reader.readLine().toLowerCase().charAt(0);

		// If user input is not 'a', 'b', or 'c', print error and return early
		if (reportOption != 'a' && reportOption != 'b' && reportOption != 'c') {

			System.out.println("I don't understand that input... returning to menu...");

			return;

		}

		// Print selected report by calling appropriate method
		if (reportOption == 'a') { // ToppingPopularity report

			DBNinja.printToppingPopReport();

		} else if (reportOption == 'b') { // ProfitByPizza report

			DBNinja.printProfitByPizzaReport();

		} else { // ProfitByOrderType report

			DBNinja.printProfitByOrderType();

		}

	}

	// Prompt - NO CODE SHOULD TAKE PLACE BELOW THIS LINE
	// DO NOT EDIT ANYTHING BELOW HERE, THIS IS NEEDED TESTING.
	// IF YOU EDIT SOMETHING BELOW, IT BREAKS THE AUTOGRADER WHICH MEANS YOUR GRADE WILL BE A 0 (zero)!!

	public static void PrintMenu() {

		System.out.println("\n\nPlease enter a menu option:");
		System.out.println("1. Enter a new order");
		System.out.println("2. View Customers ");
		System.out.println("3. Enter a new Customer ");
		System.out.println("4. View orders");
		System.out.println("5. Mark an order as completed");
		System.out.println("6. View Inventory Levels");
		System.out.println("7. Add Inventory");
		System.out.println("8. View Reports");
		System.out.println("9. Exit\n\n");
		System.out.println("Enter your option: ");

	}

	/*
	 * autograder controls....do not modiify!
	 */

	public final static String autograder_seed = "6f1b7ea9aac470402d48f7916ea6a010";
	
	private static void autograder_compilation_check() {

		try {

			Order o = null;
			Pizza p = null;
			Topping t = null;
			Discount d = null;
			Customer c = null;
			ArrayList<Order> alo = null;
			ArrayList<Discount> ald = null;
			ArrayList<Customer> alc = null;
			ArrayList<Topping> alt = null;
			double v = 0.0;
			String s = "";

			DBNinja.addOrder(o);
			DBNinja.addPizza(p);
			DBNinja.useTopping(p, t, false);
			DBNinja.usePizzaDiscount(p, d);
			DBNinja.useOrderDiscount(o, d);
			DBNinja.addCustomer(c);
			DBNinja.completeOrder(o);
			alo = DBNinja.getOrders(false);
			o = DBNinja.getLastOrder();
			alo = DBNinja.getOrdersByDate("01/01/1999");
			ald = DBNinja.getDiscountList();
			d = DBNinja.findDiscountByName("Discount");
			alc = DBNinja.getCustomerList();
			c = DBNinja.findCustomerByPhone("0000000000");
			alt = DBNinja.getToppingList();
			t = DBNinja.findToppingByName("Topping");
			DBNinja.addToInventory(t, 1000.0);
			v = DBNinja.getBaseCustPrice("size", "crust");
			v = DBNinja.getBaseBusPrice("size", "crust");
			DBNinja.printInventory();
			DBNinja.printToppingPopReport();
			DBNinja.printProfitByPizzaReport();
			DBNinja.printProfitByOrderType();
			s = DBNinja.getCustomerName(0);

		} catch (SQLException | IOException e) {

			e.printStackTrace();

		}

	}

}