import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;

public class Main{

    public static Map<String, Integer> parseCommandLineArgs(String[] args) {
        Map<String, Integer> parameters = new HashMap<>();
        try {
            for (int i = 0; i < args.length; i++) {
                if (args[i].startsWith("-")) {
                    String parameterName = args[i].substring(1);
                    if (i + 1 < args.length) {
                        try {
                            int parameterValue = Integer.parseInt(args[i + 1]);
                            parameters.put(parameterName, parameterValue);
                            i++;
                        } catch (NumberFormatException e) {
                            System.err.println("Error: Invalid value for parameter " + parameterName + ": " + args[i + 1]);
                            return null;
                        }
                    } else {
                        System.err.println("Error: Missing value for parameter " + parameterName);
                        return null;
                    }
                } else {
                    System.err.println("Warning: Ignoring invalid argument: " + args[i]);
                }
            }
        } catch (Exception e) {
            System.err.println("An unexpected error occurred: " + e.getMessage());
            return null;
        }

        return parameters;
    }
    public static Map.Entry<Character, Integer> processChar(char inputChar) {
        if (inputChar == 'a' || inputChar == 'b' || inputChar == 'c') {
            return new AbstractMap.SimpleEntry<>(inputChar,0);
        } else if (Character.isDigit(inputChar)) { // Use Character.isDigit()
            return new AbstractMap.SimpleEntry<>(inputChar,1);
        } else {
            return new AbstractMap.SimpleEntry<>(inputChar,2);
        }
    }

    public static void main(String[] args) {
        Map<String, Integer> atmParams = parseCommandLineArgs(args);

        if (atmParams != null) {
            int t = atmParams.getOrDefault("t", 0);
            int k = atmParams.getOrDefault("k", 0);
            int m = atmParams.getOrDefault("m", 0);
            int n = atmParams.getOrDefault("n", 0);

            ATM atm = new ATM();
            CardReader cr = new CardReader(atm);
            Display display = new Display();
            display.display(Display.get_default_display());
            atm.setMinimumAmount(n);
            atm.setTotalFund(t);
            atm.setMaximum_withdrawar_pday_pacc(k);
            atm.setMaximum_withdrawar_ptrans(m);

            while (true) {

                Message msg = atm.checkAvailabilityOfCashInATM();
                if (msg.require_change) {
                    display.display(msg.msg);
                }
                // TODO wait for signal from card reader
                // while (cardreader.readcard == null ??)
                Card card = cr.readCard();
                if(card.getFails() >= 3) {
                    cr.retainCard();
                    break;
                }
                display.display("enter pin");

                Scanner scanner = new Scanner(System.in);
                String inputchar = scanner.next(); // Reads a whole line
                Map.Entry<Character, Integer> option = processChar(inputchar.charAt(0));
                ArrayList<Integer> pin = new ArrayList<Integer>();
                switch (option.getValue()) {
                    case 0:
                        switch(option.getKey()) {
                            case 'a':
                                pin.clear();
                                break;
                            case 'b':
                                if (pin.size()!= 4) {
                                    display.display("ERR " + pin.size() + "is not correct number of characters for a pin");
                                    System.exit(0);
                                }

                                if (card.getPin() == pin) {
                            // successfully pass
                            // maybe move to function and return smt;
                                    break;
                                }
                        else {
                            card.setFails(card.getFails() + 1);
                        }
                        // start from top to check for fails
                                break;
                            case 'c':
                                cr.ejectCard();
                                break;
                        }
                        break;
                    case 1:
                   if (pin.size() >= 4) {
                        display.display("ERR " + pin.size() + "is not correct number of characters for a pin");
                        pin.clear();
                        //sleep(2);
                        display.display("password: ");
                    } else {
                        pin.add(Integer.parseInt(option.getKey().toString()));
                        display.display(display.getMesssage() + "*");
                    }
                        break;
                    case 2:
                        display.display("ERR unknown option" );
                        break;

                    default:
                        break;
                }
            }

        } else {
            System.err.println("Failed to initialize ATM parameters from command line.");
        }
    }
}
