import java.awt.BorderLayout;
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

/**
 * Jendela utama aplikasi Buku Kontak.
 * JFrame tidak bisa dibuat pada lingkungan tanpa layar, sehingga
 * perakitan isi jendela dipisahkan ke method static bangunPanelTombol
 * yang bisa diuji tanpa membuka jendela nyata.
 */
public class JendelaUtama extends JFrame {

    public JendelaUtama(DaftarKontak daftar) {
        super("Buku Kontak");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        KontakTableModel model = new KontakTableModel(daftar);
        PanelFormKontak form = new PanelFormKontak();
        PanelTabelKontak tabel = new PanelTabelKontak(model);
        JLabel status = new JLabel("Siap.");
        JPanel tombol = bangunPanelTombol(form, model, tabel, status);

        JPanel selatan = new JPanel(new BorderLayout(4, 4));
        selatan.add(tombol, BorderLayout.NORTH);
        selatan.add(status, BorderLayout.SOUTH);

        JPanel isi = new JPanel(new BorderLayout(8, 8));
        isi.add(form, BorderLayout.NORTH);
        isi.add(tabel, BorderLayout.CENTER);
        isi.add(selatan, BorderLayout.SOUTH);
        setContentPane(isi);

        pack();
        setLocationRelativeTo(null);
    }

    /**
     * Membangun panel tombol beserta seluruh aksinya.
     * Setiap tombol hanya membaca formulir, memanggil satu operasi
     * KontakTableModel, lalu melaporkan hasil pada label status.
     */
    static JPanel bangunPanelTombol(PanelFormKontak form, KontakTableModel model,
            PanelTabelKontak tabel, JLabel status) {
        JPanel tombol = new JPanel(new FlowLayout(FlowLayout.LEADING));

        JButton tambah = new JButton("Tambah");
        tambah.addActionListener(e -> {
            try {
                Kontak baru = model.tambah(form.nama(), form.email(), form.telepon());
                form.kosongkan();
                tabel.pilihBaris(model.jumlahBaris() - 1);
                status.setText("Kontak " + baru.nama() + " (id " + baru.id() + ") ditambahkan.");
            } catch (KontakInvalidException | PersistensiGagalException ex) {
                status.setText("Gagal menambah: " + ex.getMessage());
            }
        });

        JButton ubah = new JButton("Ubah");
        ubah.addActionListener(e -> {
            int id = tabel.idTerpilih();
            if (id < 0) {
                status.setText("Pilih kontak pada tabel terlebih dahulu.");
                return;
            }
            try {
                Kontak baru = model.ubah(id, form.nama(), form.email(), form.telepon());
                status.setText("Kontak id " + baru.id() + " diubah menjadi " + baru.nama() + ".");
            } catch (KontakInvalidException | KontakTidakDitemukanException
                    | PersistensiGagalException ex) {
                status.setText("Gagal mengubah: " + ex.getMessage());
            }
        });

        JButton hapus = new JButton("Hapus");
        hapus.addActionListener(e -> {
            int id = tabel.idTerpilih();
            if (id < 0) {
                status.setText("Pilih kontak pada tabel terlebih dahulu.");
                return;
            }
            try {
                Kontak terhapus = model.hapus(id);
                status.setText("Kontak " + terhapus.nama() + " (id " + id + ") dihapus.");
            } catch (KontakTidakDitemukanException | PersistensiGagalException ex) {
                status.setText("Gagal menghapus: " + ex.getMessage());
            }
        });

        JTextField isianCari = new JTextField(10);
        JButton cari = new JButton("Cari");
        cari.addActionListener(e -> {
            tabel.saring(isianCari.getText());
            status.setText(tabel.tabel().getRowCount() + " kontak cocok untuk \""
                    + isianCari.getText().strip() + "\".");
        });

        tombol.add(tambah);
        tombol.add(ubah);
        tombol.add(hapus);
        tombol.add(isianCari);
        tombol.add(cari);
        return tombol;
    }
}
