import java.math.BigDecimal;
import java.time.YearMonth;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.Map;

/** Bagian 3: ringkasan bulanan, per kategori, partisi nominal, dan tren antar bulan. */
public class DemoKeuangan {

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

        // 1) Ringkasan per bulan: groupingBy + teeing + filtering.
        Map<YearMonth, LaporanBulanan> perBulan = AnalisisKeuangan.laporanPerBulan(semua);
        System.out.println("=== Ringkasan per bulan ===");
        for (Map.Entry<YearMonth, LaporanBulanan> e : perBulan.entrySet()) {
            LaporanBulanan l = e.getValue();
            System.out.printf(Locale.US, "%s  masuk %,13.2f  keluar %,13.2f  selisih %,13.2f%n",
                    e.getKey(), l.totalPemasukan(), l.totalPengeluaran(), l.selisih());
        }

        // 2) Tren selisih antar bulan berurutan.
        System.out.println();
        System.out.println("=== Tren selisih antar bulan ===");
        List<Map.Entry<YearMonth, LaporanBulanan>> urut = List.copyOf(perBulan.entrySet());
        for (int i = 1; i < urut.size(); i++) {
            BigDecimal sebelum = urut.get(i - 1).getValue().selisih();
            BigDecimal kini = urut.get(i).getValue().selisih();
            BigDecimal delta = kini.subtract(sebelum);
            String arah = delta.signum() >= 0 ? "naik" : "turun";
            System.out.printf(Locale.US, "%s -> %s : %-5s %,13.2f%n",
                    urut.get(i - 1).getKey(), urut.get(i).getKey(), arah, delta.abs());
        }

        // 3) Pengeluaran per kategori pada Februari, terurut dari yang terbesar.
        System.out.println();
        System.out.println("=== Pengeluaran per kategori — Februari 2026 ===");
        Map<String, BigDecimal> perKategori =
                AnalisisKeuangan.pengeluaranPerKategori(semua, YearMonth.of(2026, 2));
        perKategori.entrySet().stream()
                .sorted(Map.Entry.<String, BigDecimal>comparingByValue(Comparator.reverseOrder())
                        .thenComparing(Map.Entry.comparingByKey()))
                .forEach(e -> System.out.printf(Locale.US, "%-13s %,13.2f%n",
                        e.getKey(), e.getValue()));

        // 4) Partisi nominal: pengeluaran di atas versus di bawah ambang.
        System.out.println();
        BigDecimal ambang = new BigDecimal("500000.00");
        System.out.printf(Locale.US, "=== Partisi nominal Februari (ambang %,.2f) ===%n", ambang);
        Map<Boolean, List<Transaksi>> partisi =
                AnalisisKeuangan.partisiNominal(semua, YearMonth.of(2026, 2), ambang);
        System.out.println("Di atas ambang : " + partisi.get(true).size() + " transaksi");
        for (Transaksi t : partisi.get(true)) {
            System.out.printf(Locale.US, "  %s  %-13s %,13.2f  %s%n",
                    t.tanggal(), t.kategori(), t.jumlah(), t.keterangan());
        }
        System.out.println("Di bawah ambang: " + partisi.get(false).size() + " transaksi");
        for (Transaksi t : partisi.get(false)) {
            System.out.printf(Locale.US, "  %s  %-13s %,13.2f  %s%n",
                    t.tanggal(), t.kategori(), t.jumlah(), t.keterangan());
        }
    }
}
