import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.Date;



/**
 * Utility class for loading a collection of books from a text file.
 * 
 * @author Alvin Chao
 * @author R.Grove
 * @version 2016-11-26
 */
public class Driver {
    
    /**
     * Load the Patron file.
     * 
     * The data file should contain four comma-separated values pre line:
     * name, email, number (int), balance (double)
     * @param fileName = name of file for input.
     * @return Patron[] array of patrons.
     */
    public static Patron[] loadPatrons(String fileName) {
        ArrayList<Patron> patronList = new ArrayList<>();
        
        Scanner inFile = null;
        try {
            inFile = new Scanner(new File(fileName));
            while (inFile.hasNextLine()) {
                String[] terms = inFile.nextLine().split(",");
                Patron patron = new Patron(terms[0], terms[1],
                                           Integer.parseInt(terms[2].trim()),
                                           Double.parseDouble(terms[3].trim()));
                patronList.add(patron);
            }            
        } catch (IOException e) {
            System.out.println("Error reading patron file: " + fileName);
            System.exit(0);
        } finally {
            if (inFile != null) {
                inFile.close();
            }
        }
        
        return patronList.toArray(new Patron[0]);
    }
    
    
    /**
     * Load a set of books from the provided file.
     * 
     * @param fileName - The name of the file to load.
     * @param patrons - Array of patron objects one per ptraon from patron file.
     * @return - An array of Book objects, one per Book stored in the file
     */
    public static Book[] loadBooks(String fileName, Patron[] patrons) {
        Book[] books = null;
        String getLine;
        String[] splitLine;
        int rating;
        String[] reviewText;
        int numLines = 0;
        int bookIndex = 0;
        
        try {
            numLines = countLines(fileName);
            books = new Book[numLines];
            
            Scanner scanner = new Scanner(new File(fileName));
            // fields: title author year isbn pages
            while (scanner.hasNextLine()) {
                getLine = scanner.nextLine();
                // splitLine = getLine.split("[\\p{Punct}\\s]+");
                splitLine = getLine.split("~");
                String title = splitLine[0];
                String author = splitLine[1];
                String isbn = splitLine[2];
                int year = Integer.parseInt(splitLine[3]);
                int pages = Integer.parseInt(splitLine[4]);
                // create book
                books[bookIndex] = new Book(title, author, isbn, year, pages);
                // setup an initial dueDate of today
                Date dueDate = new Date();
                double rand2 = Math.random() * 60;
                int randLate = (int) rand2;  
                dueDate = DateUtils.addDays(dueDate, -randLate);
                int numPatrons = patrons.length;
                // for every 5th book - check it out to a random patron.
                if (bookIndex / 5 == 0) {
                    double rand = Math.random() * numPatrons;
                    int randPatron = (int) rand;
                    books[bookIndex].checkout(patrons[randPatron], dueDate);
                }
                bookIndex++;
            }
        } catch (FileNotFoundException e) {
            System.out.println("Problem reading " + fileName);
        }
        return books;
    }
    
    /**
     * Helper method for determining the number of lines in the file.
     * 
     * @param fileName - Name of the file
     * @return The number of lines in the file
     * @throws FileNotFoundException If the file cannot be opened for reading
     */
    private static int countLines(String fileName)
        throws FileNotFoundException {
        
        int numLines = 0;
        
        Scanner scanner = new Scanner(new File(fileName));
        
        while (scanner.hasNextLine()) {
            scanner.nextLine();
            numLines++;
        }
        return numLines;
    }
    
    /**
     * List all books in the library.
     * @param catalog = array of all books in libary.
     */
    public static void listCatalog(Book[] catalog) {
        // output the book catalog to the screen
        for (Book book: catalog) {
            String title = book.getTitle();
            String author = book.getAuthor();
            String isbn = book.getIsbn();
            int year = book.getYear();
            int pages = book.getPages();
            int status = book.getStatus();
            Date dueDate = book.getDue();
            System.out.println(title + "\t\t" + author + "\t\t"
                                   + isbn + "\t\t" + year + "\t\t" + pages 
                                   + "\t\t" + status + "\t\t" + dueDate);
        }
    }
    
    /**
     * List the Patron array.
     * 
     * @param patrons The Patron array
     */
    public static void listPatrons(Patron[] patrons) {
        for (Patron patron : patrons) {
            System.out.println(patron.toString());
        }
    }
    
    /**
     * Main Method.
     * Used to load and test books.
     * @param args = command line arguments.
     */
    public static void main(String[] args) {
        // filename lflbooks.txt
        
        String filename = "lflbooks.txt";
        
        // load patrons from file patrons.txt
        Patron[] patrons = loadPatrons("patrons.txt");
        
        // load the books from the file into the catalog
        Book[] catalog = loadBooks(filename, patrons);
        
        
        Library library = new Library(catalog, patrons);
        
        // Checkout some default books
        
        
        Scanner input = new Scanner(System.in);
        char option;
        
        do {
            System.out.println("\nEnter an option:");
            System.out.println("  B: List the book catalog");
            System.out.println("  b: List the details of a book");
            System.out.println("  P: List the Patrons");
            System.out.println("  p: List details of a patron");
            System.out.println("  S: Search for a book");
            System.out.println("  O: Check out a book");
            System.out.println("  I: Check in a book");
            System.out.println("  F: Determine the fine amount for a book");
            System.out.println("  Q: Quit");
            System.out.print("Option: ");
            
            String inLine = input.nextLine();
            if (inLine.length() > 0) {
                option = inLine.charAt(0);
            } else {
                option = ' ';
            }
            
            if (option  == 'B') {
                listCatalog(catalog);
            }
            if (option  == 'b') {
                System.out.print("Enter ISBN: ");
                String isbn = input.nextLine();
                for (Book b : catalog) {
                    if (isbn.equals(b.getIsbn())) {
                        System.out.println("Title: " + b.getTitle());
                        System.out.println("Author: " + b.getAuthor());
                        System.out.println("Year: " + b.getYear());
                        System.out.println("Pages: " + b.getPages());
                        System.out.println("Status: " + b.getStatus());
                        System.out.println("Due: " + b.getDue());
                        System.out.println("Patron: " + b.getPatron());
                    }
                }
            } else if (option  == 'P') {
                listPatrons(patrons);
            } else if (option  == 'p') {
                System.out.print("Enter Patron Nr: ");
                Integer patronNr = Integer.parseInt(input.nextLine());
                for (int x = 0; x < patrons.length; x++) {
                    if (patrons[x].equals(patronNr)) {
                        System.out.println(patrons[x].toString());
                    }
                }
            } else if (option  == 'S') {
                System.out.print("Enter Title: ");
                String searchTitle = input.nextLine();
                for (Book b : catalog) {
                    if (searchTitle.equals(b.getTitle())) {
                        System.out.println("Title: " + b.getTitle());
                        System.out.println("Author: " + b.getAuthor());
                        System.out.println("Year: " + b.getYear());
                        System.out.println("Pages: " + b.getPages());
                        System.out.println("Status: " + b.getStatus());
                        System.out.println("Due: " + b.getDue());
                        System.out.println("Patron: " + b.getPatron());
                    }
                }
                
            } else if (option  == 'O') {
                Book book = null;
                Patron patron = null;
                
                System.out.print("Enter ISBN: ");
                String isbn = input.nextLine();
                for (Book b : catalog) {
                    if (isbn.equals(b.getIsbn())) {
                        book = b;
                    }
                }
                if (book == null) {
                    System.out.println("That ISBN is not in the catalog.");
                    continue;
                }
                
                System.out.print("Enter Patron Nr: ");
                Integer patronNr = Integer.parseInt(input.nextLine());
                for (Patron p : patrons) {
                    if (p.equals(patronNr)) {
                        patron = p;
                    }
                }
                if (patron == null) {
                    System.out.println("That patron number does not exist.");
                    continue;
                }
                
                library.checkout(book, patron);     
            } else if (option  == 'I') {
                Book book = null;
                
                System.out.print("Enter ISBN: ");
                String isbn = input.nextLine();
                for (Book b : catalog) {
                    if (isbn.equals(b.getIsbn())) {
                        book = b;
                    }
                }
                if (book == null) {
                    System.out.println("That ISBN is not in the catalog.");
                    continue;
                }
                
                library.checkin(book);
                
            } else if (option  == 'F') {
                System.out.print("Enter ISBN: ");
                String isbn = input.nextLine();
                for (Book b : catalog) {
                    if (isbn.equals(b.getIsbn())) {
                        double fine = library.determineFine(b);
                        System.out.printf("Fine: %.2f%n", fine);
                    }
                }
            }
            
        } while (Character.toLowerCase(option) != 'q');
        
    }
}
