import java.time.LocalDate;
import java.util.Objects;

// Transaksi sirkulasi: tanggalKembali berubah saat buku dikembalikan,
// sehingga Peminjaman dibuat sebagai class biasa, bukan record.
public class Peminjaman {

    /** Lama peminjaman standar, dalam hari. */
    public static final int LAMA_PINJAM_HARI = 14;

    private final Buku buku;
    private final Anggota anggota;
    private final LocalDate tanggalPinjam;
    private final LocalDate jatuhTempo;
    private LocalDate tanggalKembali; // null selama buku belum kembali

    public Peminjaman(Buku buku, Anggota anggota, LocalDate tanggalPinjam) {
        this.buku = Objects.requireNonNull(buku, "buku tidak boleh null");
        this.anggota = Objects.requireNonNull(anggota, "anggota tidak boleh null");
        this.tanggalPinjam =
                Objects.requireNonNull(tanggalPinjam, "tanggalPinjam tidak boleh null");
        this.jatuhTempo = tanggalPinjam.plusDays(LAMA_PINJAM_HARI);
    }

    public Buku buku() {
        return buku;
    }

    public Anggota anggota() {
        return anggota;
    }

    public LocalDate tanggalPinjam() {
        return tanggalPinjam;
    }

    public LocalDate jatuhTempo() {
        return jatuhTempo;
    }

    /** Tanggal kembali aktual; null bila buku masih di tangan anggota. */
    public LocalDate tanggalKembali() {
        return tanggalKembali;
    }

    /** Apakah buku masih dipinjam? */
    public boolean aktif() {
        return tanggalKembali == null;
    }

    /** Catat pengembalian dan kunci transaksi agar tidak dikembalikan dua kali. */
    public void kembalikan(LocalDate tanggal) {
        Objects.requireNonNull(tanggal, "tanggal tidak boleh null");
        if (tanggal.isBefore(tanggalPinjam)) {
            throw new IllegalArgumentException(
                    "tanggal kembali " + tanggal + " lebih awal dari tanggal pinjam "
                            + tanggalPinjam);
        }
        if (!aktif()) {
            throw new IllegalStateException("peminjaman sudah selesai");
        }
        this.tanggalKembali = tanggal;
    }

    // toString eksplisit: hanya memuat data domain, tanpa alamat objek.
    @Override
    public String toString() {
        return "Peminjaman[judul=" + buku.judul() + ", anggota=" + anggota.nama()
                + ", pinjam=" + tanggalPinjam + ", jatuhTempo=" + jatuhTempo
                + ", kembali=" + (aktif() ? "-" : tanggalKembali) + "]";
    }
}
