import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

/** Bagian 4: menyimpan buku kas ke berkas, lalu memuatnya kembali dengan validasi. */
public class DemoKeuangan {

    public static void main(String[] args) throws Exception {
        BukuKas kas = new BukuKas();
        DemoData.daftarkanKategori(kas);
        for (Transaksi t : DemoData.contohTransaksi()) {
            kas.tambah(t);
        }

        // 1) Simpan seluruh buku kas lalu peragakan isi berkasnya.
        Path berkas = Path.of("kas-budi.txt");
        PenyimpananKas.simpan(kas.semua(), berkas);
        System.out.println("Tersimpan " + kas.jumlahTransaksi() + " transaksi ke " + berkas);
        System.out.println();
        System.out.println("=== Isi kas-budi.txt ===");
        System.out.print(Files.readString(berkas, StandardCharsets.UTF_8));
        System.out.println();

        // 2) Muat ulang: seluruh baris harus lolos validasi dan checksum.
        PenyimpananKas.HasilMuat hasil = PenyimpananKas.muat(berkas);
        System.out.println("=== Muat ulang kas-budi.txt ===");
        System.out.println("Transaksi dimuat : " + hasil.transaksi().size());
        System.out.println("Galat            : " + hasil.galat().size());

        BukuKas kasBaru = new BukuKas();
        DemoData.daftarkanKategori(kasBaru);
        for (Transaksi t : hasil.transaksi()) {
            kasBaru.tambah(t);
        }
        System.out.printf(Locale.US, "Saldo asli       : %,14.2f%n", kas.saldo());
        System.out.printf(Locale.US, "Saldo dimuat     : %,14.2f%n", kasBaru.saldo());
        System.out.println("Data identik     : " + kasBaru.semua().equals(kas.semua()));

        // 3) Berkas cacat: tiga baris rusak, checksum sengaja dihitung ulang benar.
        Path cacat = Path.of("kas-cacat.txt");
        List<String> barisCacat = new ArrayList<>();
        barisCacat.add(PenyimpananKas.HEADER);
        barisCacat.add("T;2026-01-05;Gaji bulanan Januari;PEMASUKAN;Gaji;8500000.00");
        barisCacat.add("T;15-01-2026;Tanggal terbalik;PENGELUARAN;Sewa;250000.00");
        barisCacat.add("T;2026-01-07;Sewa tempat tinggal Januari;PENGELUARAN;Sewa;2500000.00");
        barisCacat.add("T;2026-01-10;Belanja bahan makanan;PENGELUARAN;Makanan;bukan-angka");
        barisCacat.add("T;2026-01-18;Makan di luar bersama Siti;KELUAR;Makanan;380000.00");
        barisCacat.add(PenyimpananKas.PREFIX_CHECKSUM + PenyimpananKas.checksum(barisCacat));
        Files.write(cacat, barisCacat, StandardCharsets.UTF_8);

        System.out.println();
        System.out.println("=== Muat kas-cacat.txt ===");
        PenyimpananKas.HasilMuat hasilCacat = PenyimpananKas.muat(cacat);
        for (String g : hasilCacat.galat()) {
            System.out.println("GALAT: " + g);
        }
        System.out.println("Transaksi lolos  : " + hasilCacat.transaksi().size());

        // 4) Berkas yang nominalnya diubah diam-diam setelah checksum ditulis.
        Path manipulasi = Path.of("kas-manipulasi.txt");
        List<String> barisUbah = new ArrayList<>(Files.readAllLines(berkas, StandardCharsets.UTF_8));
        barisUbah.set(1, barisUbah.get(1).replace("8500000.00", "8500000.01"));
        Files.write(manipulasi, barisUbah, StandardCharsets.UTF_8);

        System.out.println();
        System.out.println("=== Muat kas-manipulasi.txt ===");
        PenyimpananKas.HasilMuat hasilManip = PenyimpananKas.muat(manipulasi);
        for (String g : hasilManip.galat()) {
            System.out.println("GALAT: " + g);
        }
        System.out.println("Transaksi lolos  : " + hasilManip.transaksi().size()
                + " — seluruh isi ditolak karena integritas diragukan");
    }
}
