import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class ContohIntegrasi {

    record Item(String nama, int jumlah, long hargaSatuan) {
        long subtotal() {
            return jumlah * hargaSatuan;
        }
    }

    record Pesanan(String id, String pelanggan, List<Item> items) {
        long total() {
            return items.stream().mapToLong(Item::subtotal).sum();
        }
    }

    // komponen 1: validasi masukan

    static final class ValidatorPesanan {

        void periksa(Pesanan pesanan) {
            if (pesanan.id() == null || !pesanan.id().startsWith("PSN-")) {
                throw new IllegalArgumentException("id harus berawalan PSN-");
            }
            if (pesanan.items().isEmpty()) {
                throw new IllegalArgumentException("pesanan tanpa item");
            }
            for (Item item : pesanan.items()) {
                if (item.jumlah() <= 0) {
                    throw new IllegalArgumentException(
                        "jumlah item harus positif: " + item.nama());
                }
            }
        }
    }

    // komponen 2: penyimpanan (versi in-memory)

    static final class RepoPesanan {

        private final Map<String, Pesanan> tabel = new LinkedHashMap<>();

        void simpan(Pesanan pesanan) {
            tabel.put(pesanan.id(), pesanan);
        }

        Pesanan cari(String id) {
            return tabel.get(id);
        }

        int jumlah() {
            return tabel.size();
        }
    }

    // komponen 3: layanan yang merangkai validator dan penyimpanan

    static final class LayananPesanan {

        private final ValidatorPesanan validator;
        private final RepoPesanan repo;

        LayananPesanan(ValidatorPesanan validator, RepoPesanan repo) {
            this.validator = validator;
            this.repo = repo;
        }

        String kirim(Pesanan pesanan) {
            validator.periksa(pesanan);
            repo.simpan(pesanan);
            return "OK-" + pesanan.id();
        }
    }

    public static void main(String[] args) {
        RepoPesanan repo = new RepoPesanan();
        LayananPesanan layanan = new LayananPesanan(new ValidatorPesanan(), repo);

        // skenario 1: pesanan valid mengalir sampai tersimpan
        Pesanan valid = new Pesanan("PSN-1", "Budi", List.of(
            new Item("Buku Java", 2, 85_000L),
            new Item("Pulpen", 5, 12_000L)));
        String hasil = layanan.kirim(valid);
        Pesanan tersimpan = repo.cari("PSN-1");

        System.out.println("hasil        = " + hasil);
        System.out.println("tersimpan    = " + (tersimpan != null));
        System.out.println("total        = " + tersimpan.total());
        System.out.println("pelanggan    = " + tersimpan.pelanggan());

        // skenario 2: pesanan tanpa item ditolak di depan pipeline
        try {
            layanan.kirim(new Pesanan("PSN-2", "Siti", List.of()));
        } catch (IllegalArgumentException e) {
            System.out.println("ditolak      = " + e.getMessage());
        }
        System.out.println("jumlah baris = " + repo.jumlah());
    }
}
