/*
 * 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 logic;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Scanner;
import java.util.regex.Pattern;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;

/**
 *
 * @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 final String PATH_CONTI = "./src/logic/conti/";
    private static ArrayList<ContoCorrente> conti;

    public static void setConti(ArrayList<ContoCorrente> conti) {
        MyBank.conti = conti;
    }

    public static ArrayList<ContoCorrente> getConti() {
        return conti;
    }

    public static List<ContoCorrente> importaConti() throws IOException{
        ArrayList<ContoCorrente> conti = new ArrayList<>();
        File percorsoConti = new File(PATH_CONTI);
        ObjectMapper mapper = new ObjectMapper();
        mapper.setDateFormat(new SimpleDateFormat("dd/MM/yyyy"));
        StringBuilder sb;
        String riga;

        if (percorsoConti.exists() && percorsoConti.listFiles().length != 0) {
            for (File conto : percorsoConti.listFiles()) {
                if (conto.getName().substring(conto.getName().lastIndexOf(".")).equals(".json")) {
                    try (BufferedReader bf = new BufferedReader(new FileReader(conto))) {
                        sb = new StringBuilder();
                        riga = bf.readLine();

                        while (riga != null) {
                            sb.append(riga);
                            riga = bf.readLine();
                        }
                        conti.add(mapper.readerFor(ContoCorrente.class).readValue(sb.toString()));

                        ArrayList<Integer> numeriContiCorrenti = (ArrayList<Integer>) ContoCorrente
                                .getNumeriContiCorrenti();
                        numeriContiCorrenti.add(conti.getLast().getNumeroContoCorrente());
                        ContoCorrente.setNumeriContiCorrenti(numeriContiCorrenti);

                    } catch (IOException e) {
                        throw new IOException("Errore nella lettura del file di conto corrente:\n" + e.getMessage());
                    }
                }
            }
        }
        return conti;
    }

    public static ContoCorrente aggiungiConto(String nome, String cognome, String codiceFiscale, Date dataDiNascita,
            double saldoIniziale) throws IOException{
        int numeroContoCorrente;
        ContoCorrente contoCorrente;
        boolean exit = false;
        int i = 0;

        numeroContoCorrente = Math.abs(codiceFiscale.hashCode());

        if (ContoCorrente.getNumeriContiCorrenti().contains(numeroContoCorrente)) {
            for (; i < conti.size() && exit; i++) {
                exit = conti.get(i).getNumeroContoCorrente() == numeroContoCorrente;
            }
            contoCorrente = conti.get(i);
        } else {
            File percorsoConti = new File(PATH_CONTI);
            if (!percorsoConti.exists()) {
                percorsoConti.mkdir();
            }
            contoCorrente = new ContoCorrente(nome, cognome, codiceFiscale, dataDiNascita, saldoIniziale,
                    numeroContoCorrente);
            conti.add(contoCorrente);
            salvaContoCorrente(contoCorrente);
        }

        return contoCorrente;
    }

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

    public static Date dataDiNascita(String dataDiNascita) throws ParseException {
        final String FORMATO_DATA = "dd/MM/yyyy";
        SimpleDateFormat sdf = new SimpleDateFormat(FORMATO_DATA);
        sdf.setLenient(false);
        return sdf.parse(dataDiNascita);
    }

    public static double valoreDouble(String numeroDouble) throws NumberFormatException {
        double valoreDouble;

        valoreDouble = Double.parseDouble(numeroDouble);

        if (valoreDouble <= 0) {
            throw new NumberFormatException();
        }

        return valoreDouble;
    }

    static void salvaContoCorrente(ContoCorrente conto) {
        try (BufferedWriter bw = new BufferedWriter(
                new FileWriter(PATH_CONTI + "conto_" + conto.getNumeroContoCorrente() + ".json"))) {
            ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
            bw.write(ow.writeValueAsString(conto));
        } catch (IOException _) {
            System.out.println("Errore: impossibile salvare il conto corrente.");
        }
    }
}
