import javax.swing.table.AbstractTableModel;

/**
 * TableModel kustom yang membaca DaftarKontak sebagai sumber data.
 * Operasi CRUD diteruskan ke DaftarKontak, lalu notifikasi perubahan
 * dikirim ke view lewat keluarga method fire... .
 */
public class KontakTableModel extends AbstractTableModel {

    private static final String[] KOLUM = { "Id", "Nama", "Email", "Telepon" };

    private final DaftarKontak daftar;

    public KontakTableModel(DaftarKontak daftar) {
        this.daftar = daftar;
    }

    @Override
    public int getRowCount() {
        return daftar.jumlah();
    }

    @Override
    public int getColumnCount() {
        return KOLUM.length;
    }

    @Override
    public String getColumnName(int kolom) {
        return KOLUM[kolom];
    }

    @Override
    public Object getValueAt(int baris, int kolom) {
        Kontak k = daftar.semua().get(baris);
        return switch (kolom) {
            case 0 -> k.id();
            case 1 -> k.nama();
            case 2 -> k.email();
            default -> k.telepon();
        };
    }

    /** Menambah kontak lewat DaftarKontak lalu memberi tahu view. */
    public Kontak tambah(String nama, String email, String telepon)
            throws KontakInvalidException, PersistensiGagalException {
        Kontak baru = daftar.tambah(nama, email, telepon);
        int baris = daftar.jumlah() - 1;
        fireTableRowsInserted(baris, baris);
        return baru;
    }

    /** Mengubah kontak lewat DaftarKontak lalu memberi tahu view. */
    public Kontak ubah(int id, String nama, String email, String telepon)
            throws KontakInvalidException, KontakTidakDitemukanException,
            PersistensiGagalException {
        int baris = barisDariId(id);
        Kontak baru = daftar.ubah(id, nama, email, telepon);
        fireTableRowsUpdated(baris, baris);
        return baru;
    }

    /** Menghapus kontak lewat DaftarKontak lalu memberi tahu view. */
    public Kontak hapus(int id)
            throws KontakTidakDitemukanException, PersistensiGagalException {
        int baris = barisDariId(id);
        Kontak terhapus = daftar.hapus(id);
        fireTableRowsDeleted(baris, baris);
        return terhapus;
    }

    /** Kontak pada baris model — dipakai aksi terhadap baris terpilih. */
    public Kontak kontakDiBaris(int baris) {
        return daftar.semua().get(baris);
    }

    /** Jumlah baris saat ini pada model. */
    public int jumlahBaris() {
        return daftar.jumlah();
    }

    private int barisDariId(int id) {
        for (int i = 0; i < daftar.jumlah(); i++) {
            if (daftar.semua().get(i).id() == id) {
                return i;
            }
        }
        return -1;
    }
}
