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

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;

/**
 *
 * @author Verde
 */
public class ContoCorrente {
    private String nome;
    private String cognome;
    private String codiceFiscale;
    private double saldo;
    private int numeroContoCorrente;

    private static ArrayList<Integer> numeriContiCorrenti = new ArrayList<>();

    @JsonFormat
      (shape = JsonFormat.Shape.STRING, pattern = "dd/MM/yyyy")
    private Date dataDiNascita;

    public ContoCorrente() {
    }

    public ContoCorrente(String nome, String cognome, String codiceFiscale, Date dataDiNascita, double saldo,
            int numeroContoCorrente) throws IOException{
        this.nome = nome;
        this.cognome = cognome;
        this.codiceFiscale = codiceFiscale;
        this.dataDiNascita = dataDiNascita;
        this.saldo = saldo;
        this.numeroContoCorrente = numeroContoCorrente;
        numeriContiCorrenti.add(numeroContoCorrente);
        log("Apertura del conto con saldo iniziale di " + this.saldo);
    }
    
    public static List<Integer> getNumeriContiCorrenti() {
        return numeriContiCorrenti;
    }

    public static void setNumeriContiCorrenti(List<Integer> numeriContiCorrenti) {
        ContoCorrente.numeriContiCorrenti = (ArrayList<Integer>)numeriContiCorrenti;
    }

    public int getNumeroContoCorrente() {
        return numeroContoCorrente;
    }

    public void versa(double quantita) throws IOException{
        this.saldo += quantita;
        log("Versamento di " + quantita + " effettuato con successo.");
        logSaldoCorrente();
    }
    
    public void preleva(double quantita) throws IllegalArgumentException, IOException{
        if (quantita > this.saldo) {
            log("Tentato prelievo di " + quantita + " fallito per superamento saldo.");
            logSaldoCorrente();
            throw new IllegalArgumentException("La quantità desiderata eccede il saldo corrente.");
        }
        else {
            this.saldo -= quantita;
            log("Prelievo di " + quantita + " effettuato con successo.");
            logSaldoCorrente();
        }
    }

    private void logSaldoCorrente() throws IOException{
        log("Saldo corrente: " + this.saldo);
    }

    private void log(String messaggio) throws IOException{
        StringBuilder sb = new StringBuilder();
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.sss dd/MM/yyyy");
        try (BufferedWriter bw = new BufferedWriter(
                new FileWriter(MyBank.PATH_CONTI + "movimenti_" + this.numeroContoCorrente + ".txt", true))) {
            sb.append("[");
            sb.append(sdf.format(new Date()));
            sb.append("] ");
            sb.append(messaggio);
            sb.append("\n");

            bw.write(sb.toString());
        } catch (IOException _) {
            throw new IOException("Errore nella scrittura del movimento.");
        }
    }

    @JsonIgnore
    public String getLog() throws IOException{
        try (BufferedReader br = new BufferedReader(
                new FileReader(MyBank.PATH_CONTI + "movimenti_" + this.numeroContoCorrente + ".txt"))) {
            return br.readAllAsString();
        } catch (IOException _) {
            throw new IOException("Errore nella lettura dei movimenti.");
        }
    }

    public String getNome() {
        return nome;
    }

    public String getCognome() {
        return cognome;
    }

    public String getCodiceFiscale() {
        return codiceFiscale;
    }

    public Date getDataDiNascita() {
        return dataDiNascita;
    }

    public double getSaldo() {
        return saldo;
    }
}