package inventory;

import java.util.Scanner;

/**
 * Main class providing command-line interface for the inventory system.
 *
 * Requirements:
 * - Menu with 6 options: Add, View, Sell, Stock, Statistics, Exit
 * - Input validation and error handling
 * - Sample data for testing
 * - User-friendly interface
 */
public class Main {

    private static InventoryManager manager;
    private static Scanner scanner;

    public static void main(String[] args) {
        System.out.println("Welcome to Inventory Management System!");
        System.out.println();

        manager = new InventoryManager();
        loadSampleData();

        try (Scanner scanner = new Scanner(System.in)) {
            Main.scanner = scanner;
            while (true) {
                 showMenu();
                 int choice = getChoice();
                 if (!handleChoice(choice)) {
                     break;
                 }
            }
        } catch (RuntimeException e) {
            System.err.printf("Unexpected error occurred: %s", e.getMessage());

        } finally {
            scanner = null;
        }
    }

    /**
     * Load sample data for testing
     */
    private static void loadSampleData() {
        manager.addProduct("B001", "Java Programming", "BOOK", 29.99, 10);
        manager.addProduct("B002", "Design Patterns", "BOOK", 35.50, 8);
        manager.addProduct("E001", "Laptop", "ELECTRONICS", 999.99, 5);
        manager.addProduct("E002", "Mouse", "ELECTRONICS", 25.99, 15);
    }

    /**
     * Display main menu options
     */
    private static void showMenu() {
        System.out.println();
        System.out.println("Choices:");
        System.out.println("\t1. Add Product");
        System.out.println("\t2. View Inventory");
        System.out.println("\t3. Sell Product");
        System.out.println("\t4. Add Stock");
        System.out.println("\t5. View Statistics");
        System.out.println("\t6. Exit");
        System.out.println();
    }

    /**
     * Get user choice with input validation
     * @return user's menu choice
     */
    private static int getChoice() {
        return getIntInput("Choice: ", 1);
    }

    /**
     * Handle user menu choice
     * @param choice - user's selected option
     * @return should application continue
     */
    private static boolean handleChoice(int choice) {
        switch (choice) {
            case 1: addProduct(); break;
            case 2: manager.viewInventory(); break;
            case 3: sellProduct(); break;
            case 4: addStock(); break;
            case 5: manager.viewStatistics(); break;
            case 6: return false;
            default: {
                System.out.println("Invalid choice.");
                return true;
            }
        }
        return true;
    }

    /**
     * Handle adding new product
     */
    private static void addProduct() {
        String id = getStringInput("Product id: ");
        String name = getStringInput("Product name: ");

        String type;
        do {
            type = getStringInput("Product type (BOOK,ELECTRONICS): ").toUpperCase();
        } while (!ProductFactory.isValidProductType(type));

        int quantity = getIntInput("Product quantity: ", 1);
        double price = getDoubleInput("Product price: ", 5.0);

        manager.addProduct(id, name, type, price, quantity);
    }

    /**
     * Handle selling product
     */
    private static void sellProduct() {
        String id = getStringInput("Product id: ");
        int quantity = getIntInput("Product quantity: ", 1);
        String discountType = getStringInput("Discount type (STUDENT,BULK,NONE)[NONE]: ").toUpperCase();

        manager.sellProduct(id,quantity,discountType);
    }

    /**
     * Handle adding stock
     */
    private static void addStock() {
        String id = getStringInput("Product id: ");
        int quantity = getIntInput("Product quantity: ", 1);

        manager.addStock(id, quantity);
    }

    private static String getStringInput(String prompt) {
        System.out.print(prompt);
        return scanner.nextLine();
    }

    private static int getIntInput(String prompt, int min) {
        int input = min - 1;
        do {
            try {
                input = Integer.parseInt(getStringInput(prompt));
            } catch (NumberFormatException nfe) {
                System.err.println("Invalid input.");
            }
        } while (input < min);
        return input;
    }

    private static double getDoubleInput(String prompt, double min) {
        double input = min - 1.0;
        do {
            try {
                input = Double.parseDouble(getStringInput(prompt));
            } catch (NumberFormatException nfe) {
                System.err.println("Invalid input.");
            }
        } while (input < min);
        return input;
    }
}