import java.util.ArrayList;
import java.util.Scanner;
import java.io.*;

public class VideoLibrary13 {
    private static       ArrayList<Video> library = new ArrayList<>();
    private static final String prompt             = "M(ovie), L(ecture), S(ee entries), F(ind), D(one): ";
    private static final String find_prompt        = "M(ovies), L(ectures, D(irectors), I(instructors): ";
    private static final String archive_filename   = "library_archive.txt";
    private static final String separator          = "----------------------------------------";

    private static int    next_collection_no        = 1;

    public static void main (String[] args) throws FileNotFoundException, IOException{
        restore_library_state();
        Scanner console = new Scanner(System.in);
        boolean done = false;
        while (! done){
            System.out.print(prompt);
            String action = console.next();
            action        = action.trim();        // remove any leading or trailing whitespace
            action        = action.toLowerCase(); // only lowercase letters
            if (action.equals("m")) {
                Video movie = add_movie(console);
                library.add(movie);
            } else if (action.equals("l")) {
                Video lectures = add_lectures(console);
                library.add(lectures);
            } else if (action.equals("s")) {
                list_videos();
            } else if (action.equals("f")) {
                find_videos(console);
            } else if (action.equals("d")) {
                store_library_state();
                System.out.println("Exiting");
                done = true;
            } else {
                 System.out.println(action + " is not a valid choice");
            }
        }
    }

    private static int get_collection_no(){
      int value = next_collection_no;
      next_collection_no += 1;
      return value;
    }

    private static Movie add_movie(Scanner console)throws FileNotFoundException{
        System.out.print("Filename: ");
        String filename   = console.next();
        File file         = new File(filename);
        Scanner input     = new Scanner(file);
        Movie movie       = movie_from_file(input);
        System.out.println(movie);
        return movie;
    }

    private static Movie movie_from_file(Scanner input){
        int collection_no = get_collection_no();
        String title      = input.nextLine();
        int length        = Integer.parseInt(input.nextLine());
        String format     = input.nextLine();
        String director   = input.nextLine();
        String studio     = input.nextLine();
        Movie movie       = new Movie(collection_no, title, length, format, director, studio);
        while (input.hasNextLine()){
            String line = input.nextLine();
            if (line.equals(separator)){
                break;
            }
            movie.add_actor(line);
        }
        return movie;
    }

    private static Lectures add_lectures(Scanner console)throws FileNotFoundException{
        System.out.print("Filename: ");
        String filename   = console.next();
        File file         = new File(filename);
        Scanner input     = new Scanner(file);
        Lectures lectures = lectures_from_file (input);
        System.out.println(lectures);
        return lectures;
    }

    private static Lectures lectures_from_file (Scanner input){
        int collection_no = get_collection_no();
        int length        = Integer.parseInt(input.nextLine());
        String format     = input.nextLine();
        String course     = input.nextLine();
        int disc_no       = Integer.parseInt(input.nextLine());
        String instructor = input.nextLine();
        Lectures lectures = new Lectures(collection_no, length, format, course, disc_no, instructor);
        while (input.hasNextLine()){
            String line = input.nextLine();
            if (line.equals(separator)){
                break;
            }
            lectures.add_lecture(line);
        }
        return lectures;
    }

    private static void list_videos(){
        for (int i = 0; i < library.size(); i++){
            Video entry = library.get(i);
            System.out.println(entry.short_string());
        }
    }

    private static void find_videos(Scanner console){
        String search_value;
        System.out.print(find_prompt);
        String action = console.next();
        action        = action.trim();        // remove any leading or trailing whitespace
        action        = action.toLowerCase(); // only lowercase letters
        if (action.equals("m")) {
            videos_for_class("Movie");
        } else if (action.equals("l")) {
            videos_for_class("Lectures");
        } else if (action.equals("d")) {
            search_value = get_search_value(console, "Movie", "director");
            videos_for_field("Movie", "director", search_value);
        } else if (action.equals("i")) {
            search_value = get_search_value(console, "Lectures", "instructor");
            videos_for_field("Lectures", "instructor", search_value);
        } else {
            System.out.println(action + " is not a valid choice");
        }
    }

    private static void videos_for_class(String class_name){
        for (int i = 0; i < library.size(); i++){
            Video entry = library.get(i);
            String entry_class_name = entry.getClass().getSimpleName();
            if (entry_class_name.equals(class_name)){
                System.out.println(entry);
                System.out.println(separator);
            }
        }
    }

    private static String get_search_value(Scanner console, String class_name, String field_name){
        System.out.print(field_name + " value: ");
        String serach_value = console.next();
        serach_value = serach_value.trim();
        return serach_value.toLowerCase(); 
    }

    private static void videos_for_field(String class_name, String field_name, String search_value){
        String list = "";
        String field_value;
        for (int i = 0; i < library.size(); i++){
            Video entry = library.get(i);
            String entry_class_name = entry.getClass().getSimpleName();
            if (entry_class_name.equals(class_name)){
                if (class_name.equals("Movie")) {
                    Movie movie = (Movie) entry;
                    field_value = movie.director().toLowerCase();
                    if (field_value.contains(search_value)) {
                        list += entry.toString() + "\n" + separator + "\n";
                    }
                } else if (class_name.equals("Lectures")) {
                    Lectures lectures = (Lectures) entry;
                    field_value = lectures.instructor().toLowerCase();
                    if (field_value.contains(search_value)) {
                        list += entry.toString() + "\n" + separator + "\n";
                    }
                }
            }
        }
        if (list.length() > 0) {
            System.out.println(list);
        } else {
            System.out.println("Could not find " + field_name + " matching " + search_value);
        }
    }

    private static void store_library_state() throws FileNotFoundException, IOException {
        String archive_text = "";
        for (int i =0; i < library.size(); i++){
            Video entry = library.get(i);
            String class_name = entry.getClass().getSimpleName();
            if (class_name.equals("Movie")) {
                archive_text += archive_movie_entry(entry);
                archive_text += "\n" + separator;   
            } else {
                archive_text += archive_lectures_entry(entry);
                archive_text += "\n" + separator;
            }
        }
        FileWriter output = new FileWriter(archive_filename);
        output.write(archive_text);
        output.close();
    }

    private static String  archive_movie_entry(Video entry){
        Movie m = (Movie) entry;
        String result = "\n" + "Movie";
        result += "\n" + m.title();
        result += "\n" + m.length();
        result += "\n" + m.format();
        result += "\n" + m.director();
        result += "\n" + m.studio();
        ArrayList<String> actors = m.actors();
        for (int i = 0; i < actors.size(); i++){
            result += "\n" + actors.get(i);
        }
        return result;
    }

    private static String archive_lectures_entry(Video entry) {
        Lectures l = (Lectures) entry;
        String result = "\n" + "Lectures";
        result += "\n" + l.length();
        result += "\n" + l.format();
        result += "\n" + l.course();
        result += "\n" + l.disc_no();
        result += "\n" + l.instructor();
        ArrayList<String> lectures = l.lectures();
        for (int i = 0; i < lectures.size(); i++){
            result += "\n" + lectures.get(i);
        }
        return result;
    }

    private static void restore_library_state() throws FileNotFoundException{
        File archive_file = new File(archive_filename);
        if (archive_file.exists()) {
            Scanner input = new Scanner(archive_file);
            input.nextLine(); // skip past blank first line
            while (input.hasNextLine()){
                String class_name = input.nextLine();
                if (class_name.equals("Movie")){
                    library.add(movie_from_file(input));
                } else {
                    library.add(lectures_from_file(input));
                }
            }
        }
    }
}
