import java.io.IOException;
import java.util.List;
import java.util.Scanner;

public class Frontend implements FrontendInterface {
    private BackendInterface backend;
    private Scanner in;
    private String min = "min";
    private String max = "max";
    private String energy = "none";
    //check whether called the getRange
    private boolean getRange = false;
    //check whether called the filterEnergeticSongs
    private boolean filter = false;

    public Frontend(Scanner in, BackendInterface backend) {
        this.in = in;
        this.backend = backend;
    }

    public void runCommandLoop() {
        boolean quit = false;
        displayMainMenu();
        while (!quit && in.hasNextLine()) {
            String input = in.nextLine().trim().toUpperCase();
            switch (input) {
                case "R":
                    readFile();
                    displayMainMenu();
                    break;
                case "G":
                    getValues();
                    getRange = true;
                    displayMainMenu();
                    break;
                case "F":
                    setFilter();
                    filter = true;
                    displayMainMenu();
                    break;
                case "D":
                    topFive();
                    displayMainMenu();
                    break;
                case "Q":
                    quit = true;
                    break;
                default:
                    System.out.println("Invalid command. Please try again.");
                    displayMainMenu();
            }
        }
    }

    public void displayMainMenu() {
        String menu = """
	    
	    ~~~ Command Menu ~~~
	        [R]ead Data
	        [G]et Songs by Danceability [min - max]
	        [F]ilter New Songs (by Min Energy: none)
	        [D]isplay Five Fastest
	        [Q]uit
	    Choose command:""";
        menu=menu.replace("min",min).replace("max",max).replace("none",energy);
        System.out.print(menu + " ");
    }

    /**
     * Provides text-based user interface and error handling for the
     * [R]ead Data command.
     */
    public void readFile() {
        System.out.println("Enter path to csv file to load: ");
        String path = in.nextLine();
        try {
            backend.readData(path);
            System.out.println("Done reading file.");
        } catch (IOException e) {
            System.out.println("Error reading file: " + e.getMessage());
        }
    }

    /**
     * Provides text-based user interface and error handling for the
     * [G]et Songs by Danceability command.
     */
    public void getValues() {
        int minValue = 0;
        int maxValue = 0;
        System.out.println("Enter range of values (MIN - MAX): ");
        String[] input = in.nextLine().trim().split("-");
        if (input.length != 2) {
            System.out.println("Invalid range. Please try again.");
            return;
        } else {
            min = input[0];
            max = input[1];
            try {
                minValue = Integer.parseInt(this.min.trim());
                maxValue = Integer.parseInt(this.max.trim());
            } catch (NumberFormatException e) {
                System.out.println("Invalid range. Please try again.");
            }
        }
        if (minValue < 0 || maxValue > 100 || minValue > maxValue) {
            System.out.println("Invalid range. Please try again.");
        } else {
            try {
                List<String> output = backend.getRange(minValue, maxValue);
                System.out.println(output.size() + " songs found between " + min + "-" + max + ":");
                for (String song : output) {
                    System.out.println("    " + song);
                }
            } catch (Exception e) {
                System.out.println("Invalid range. Please try again.");
            }
        }
    }

    /**
     * Provides text-based user interface and error handling for the
     * [F]ilter Energetic Songs (by Min Energy) command.
     */
    public void setFilter() {
        if (!getRange) {
            System.out.println("Please get range first.");
            return;
        } else {
            System.out.print("Enter minimum energy: ");
            energy = in.nextLine();
            try {
                List<String> output = backend.filterEnergeticSongs(Integer.valueOf(energy));
                System.out.println(output.size() + " songs found between " + min + " - " + max + " with energy >= " + energy + ":");
                for (String song : output) {
                    System.out.println("    " + song);
                }
            } catch (Exception e) {
                System.out.println("Invalid range. Please try again.");
            }
        }
    }

    /**
     * Provides text-based user interface and error handling for the
     * [D]isplay Five Fastest command.
     */
    public void topFive() {
        try {
            List<String> output = backend.fiveFastest();
            System.out.println("Top Five songs found between " + min + " - " + max + " with energy >= " + energy + ":");
            for (String song : output) {
                System.out.println("    " + song);
            }
        } catch (IllegalArgumentException e) {
            System.out.println("Error displaying top five: " + e.getMessage());
        } catch (Exception e) {
            System.out.println("Invalid range. Please try again.");
        }
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        IterableSortedCollection<SongInterface> songs = new ISCPlaceholder<>();
        BackendInterface backend = new Backend(songs);
        FrontendInterface frontend = new Frontend(in, backend);
        frontend.runCommandLoop();
    }
}
