/*
 * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
 * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Main.java to edit this template
 */
package mybank;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.InputMismatchException;
import java.util.List;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 *
 * @author Verde
 */
public class MyBank {

    /**
     * @param args the command line arguments
     */

    static Scanner sc = new Scanner(System.in);
    static final String ERRORE_GENERICO = "Errore: opzione non valida.";
    static final String ERRORE_CONTI_VUOTO = "Errore: è necessario aggiungere almeno un conto corrente prima di proseguire.";

    public static void main(String[] args) {
        int scelta = -1;
        ArrayList<ContoCorrente> conti = (ArrayList<ContoCorrente>) ScriviLeggiFile.importaConti();

        do {
            System.out.println("Scegliere un'opzione:");
            System.out.println("1. Aprire conto corrente");
            System.out.println("2. Stampa conto corrente");
            System.out.println("3. Versamento");
            System.out.println("4. Prelievo");
            System.out.println("5. Mostra movimenti");
            System.out.println("0. Esci");
            System.out.print("Opzione: ");

            try {
                scelta = sc.nextInt();
                sc.nextLine();

                switch (scelta) {
                    case 0:
                        break;
                    case 1:
                        aggiungiConto(conti);
                        System.out.println("Numero conto: " + conti.getLast().getNumeroContoCorrente());
                        System.out.println("Conto corrente aggiunto con successo.");
                        pausa();
                        break;
                    case 2:
                        if (conti.isEmpty()) {
                            System.out.println(ERRORE_CONTI_VUOTO);
                        } else {
                            System.out.println(selezionaConto(conti).toString());
                        }
                        pausa();
                        break;
                    case 3:
                        if (conti.isEmpty()) {
                            System.out.println(ERRORE_CONTI_VUOTO);
                        } else {
                            versa(conti);
                            System.out.println("Versamento effettuato con successo.");
                        }
                        pausa();
                        break;
                    case 4:
                        if (conti.isEmpty()) {
                            System.out.println(ERRORE_CONTI_VUOTO);
                        } else {
                            preleva(conti);
                            System.out.println("Prelievo effettuato con successo.");
                        }
                        pausa();
                        break;
                    case 5:
                        if (conti.isEmpty()) {
                            System.out.println(ERRORE_CONTI_VUOTO);
                        } else {
                            ScriviLeggiFile.stampaLog(selezionaConto(conti));
                        }
                        pausa();
                        break;
                    default:
                        System.out.println(ERRORE_GENERICO);
                        pausa();
                        break;
                }
            } catch (InputMismatchException _) {
                System.out.println(ERRORE_GENERICO);
                pausa();
            }
        } while (scelta != 0);
    }

    public static void pausa() {
        System.out.println("Premere un tasto per continuare. . .");
        sc.nextLine();
    }

    static void aggiungiConto(ArrayList<ContoCorrente> conti) {
        Persona persona;
        boolean error;
        ContoCorrente contoCorrente;
        List<String> listaCodiciFiscali;

        do {
            error = false;

            try {
                persona = persona();
                listaCodiciFiscali = ScriviLeggiFile.leggiCodiciFiscali();

                if (listaCodiciFiscali != null && listaCodiciFiscali.contains(persona.getCodiceFiscale())) {
                    System.out.println("Errore: esiste già un conto corrente per questo codice fiscale, riprovare.");
                    pausa();
                    error = true;
                } else {
                    ScriviLeggiFile.salvaCodiceFiscale(persona.getCodiceFiscale());
                    contoCorrente = new ContoCorrente(persona, quantita("del saldo iniziale"));
                    conti.add(contoCorrente);
                    ScriviLeggiFile.salvaContoCorrente(contoCorrente);
                }
            } catch (IOException e) {
                System.out.println(e.getMessage());
                error = true;
            }
        } while (error);
    }

    static Persona persona() {
        String nome;
        String cognome;
        String codiceFiscale;
        Date dataDiNascita;

        System.out.print("Inserire il proprio nome: ");
        nome = sc.nextLine().trim();

        System.out.print("Inserire il proprio cognome: ");
        cognome = sc.nextLine().trim();

        codiceFiscale = codiceFiscale();

        dataDiNascita = dataDiNascita();

        return new Persona(nome, cognome, codiceFiscale, dataDiNascita);
    }

    static String codiceFiscale() {
        String codiceFiscale;
        boolean error;
        Pattern pattern = Pattern.compile("[A-Z]{6}[ABCDEHLMPRST]{3}\\d{2}[A-Z]\\d{3}[A-Z]");
        Matcher matcher;

        do {
            error = false;
            System.out.print("Inserire il proprio codice fiscale: ");
            codiceFiscale = sc.nextLine().trim().toUpperCase();
            matcher = pattern.matcher(codiceFiscale);
            if (!matcher.find()) {
                System.out.println(ERRORE_GENERICO);
                pausa();
                error = true;
            }
        } while (error);
        return codiceFiscale;
    }

    static Date dataDiNascita() {
        Date dataDiNascita = null;
        boolean error;
        final String FORMATO_DATA = "dd/MM/yyyy";
        SimpleDateFormat sdf = new SimpleDateFormat(FORMATO_DATA);
        sdf.setLenient(false);

        do {
            error = false;
            System.out.print("Inserire la propria data di nascita nel formato " + FORMATO_DATA + ": ");
            try {
                dataDiNascita = sdf.parse(sc.nextLine());
            } catch (ParseException _) {
                System.out.println("Errore: la data inserita non è valida.");
                pausa();
                error = true;
            }
        } while (error);
        return dataDiNascita;
    }

    static double quantita(String diCheCosa) {
        double quantita = 0;
        boolean error;

        do {
            error = false;
            System.out.print("Inserire la quantità " + diCheCosa + ": ");
            try {
                quantita = sc.nextDouble();
                sc.nextLine();

                if (quantita <= 0) {
                    System.out.println("Errore: la quantità non può essere minore o uguale a zero.");
                    pausa();
                    error = true;
                }
            } catch (InputMismatchException _) {
                System.out.println(ERRORE_GENERICO);
                pausa();
                error = true;
            }
        } while (error);

        return quantita;
    }

    static void versa(ArrayList<ContoCorrente> conti) {
        selezionaConto(conti).versa(quantita("da versare"));
    }

    static void preleva(ArrayList<ContoCorrente> conti) {
        boolean error;

        do {
            error = false;
            try {
                selezionaConto(conti).preleva(quantita("da prelevare"));
            } catch (IllegalArgumentException e) {
                System.out.println(e.getMessage());
                pausa();
                error = true;
            }
        } while (error);

    }

    static ContoCorrente selezionaConto(ArrayList<ContoCorrente> conti) {
        ContoCorrente contoCorrente = new ContoCorrente();
        int numeroContoCorrente;
        boolean error;

        do {
            error = false;
            System.out.print("Inserire il proprio numero di conto: ");
            numeroContoCorrente = sc.nextInt();
            sc.nextLine();

            if (numeroContoCorrente < 0 || numeroContoCorrente >= ContoCorrente.getTotaleNumeriCorrenti()) {
                System.out.println("Errore: il conto corrente specificato non esiste.");
                pausa();
                error = true;
            } else {
                for (ContoCorrente conto : conti) {
                    if (conto.getNumeroContoCorrente() == numeroContoCorrente) {
                        contoCorrente = conto;
                        break;
                    }
                }
            }
        } while (error);
        return contoCorrente;
    }
}
