import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.LocalDate;

// Penyimpanan berbasis berkas: satu baris satu record, dipisah karakter '|'.
// Format:
//   BUKU|isbn|judul|penulis|tahunTerbit
//   ANGGOTA|id|nama|email|terdaftar
//   PEMINJAMAN|isbn|idAnggota|tanggalPinjam|jatuhTempo|tanggalKembali(- bila masih aktif)
public final class PenyimpananPerpustakaan {

    private PenyimpananPerpustakaan() {
        // kumpulan prosedur statis: tidak perlu dibuat objeknya
    }

    public static void simpan(Perpustakaan perpus, Path berkas)
            throws PersistensiGagalException {
        try (BufferedWriter tulis = Files.newBufferedWriter(berkas, StandardCharsets.UTF_8)) {
            for (Buku buku : perpus.semuaBuku()) {
                tulis.write("BUKU|" + buku.isbn() + "|" + buku.judul() + "|"
                        + buku.penulis() + "|" + buku.tahunTerbit());
                tulis.newLine();
            }
            for (Anggota a : perpus.semuaAnggota()) {
                tulis.write("ANGGOTA|" + a.id() + "|" + a.nama() + "|"
                        + a.email() + "|" + a.terdaftar());
                tulis.newLine();
            }
            for (Peminjaman p : perpus.riwayat()) {
                String kembali = p.tanggalKembali() == null
                        ? "-" : p.tanggalKembali().toString();
                tulis.write("PEMINJAMAN|" + p.buku().isbn() + "|" + p.anggota().id() + "|"
                        + p.tanggalPinjam() + "|" + p.jatuhTempo() + "|" + kembali);
                tulis.newLine();
            }
        } catch (IOException e) {
            throw new PersistensiGagalException("gagal menyimpan ke " + berkas, e);
        }
    }

    public static Perpustakaan muat(Path berkas) throws PersistensiGagalException {
        Perpustakaan perpus = new Perpustakaan();
        try (BufferedReader baca = Files.newBufferedReader(berkas, StandardCharsets.UTF_8)) {
            String baris;
            while ((baris = baca.readLine()) != null) {
                if (baris.isBlank() || baris.startsWith("#")) {
                    continue; // baris kosong dan komentar dilewati
                }
                String[] bagian = baris.split("\\|", -1);
                switch (bagian[0]) {
                    case "BUKU" -> perpus.tambahBuku(new Buku(
                            bagian[1], bagian[2], bagian[3], Integer.parseInt(bagian[4])));
                    case "ANGGOTA" -> perpus.daftarkan(new Anggota(
                            bagian[1], bagian[2], bagian[3], LocalDate.parse(bagian[4])));
                    case "PEMINJAMAN" -> {
                        Buku buku = perpus.cariBukuIsbn(bagian[1]);
                        Anggota anggota = perpus.cariAnggota(bagian[2]);
                        LocalDate kembali = "-".equals(bagian[5])
                                ? null : LocalDate.parse(bagian[5]);
                        perpus.pulihkanPeminjaman(new Peminjaman(
                                buku, anggota, LocalDate.parse(bagian[3]),
                                LocalDate.parse(bagian[4]), kembali));
                    }
                    default -> throw new PersistensiGagalException(
                            "baris tidak dikenal: " + baris);
                }
            }
        } catch (IOException e) {
            throw new PersistensiGagalException("gagal memuat dari " + berkas, e);
        }
        return perpus;
    }
}
