/* main.c -- titik masuk aplikasi manajemen kontak. */

#include "contact.h"
#include "storage.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define DB_PATH "kontak.txt"

/* Membaca satu baris dari stdin, memotong newline. */
static void baca_baris(const char *prompt, char *buf, size_t ukuran) {
    printf("%s", prompt);
    if (fgets(buf, (int)ukuran, stdin) == 0) {
        buf[0] = '\0';
        return;
    }
    size_t n = strlen(buf);
    while (n > 0 && (buf[n - 1] == '\n' || buf[n - 1] == '\r')) {
        buf[--n] = '\0';
    }
}

static int baca_int(const char *prompt, int *out) {
    char buf[32];
    baca_baris(prompt, buf, sizeof(buf));
    char *sisa = 0;
    long v = strtol(buf, &sisa, 10);
    if (sisa == buf) return 0;
    *out = (int)v;
    return 1;
}

static void menu_tambah(ContactList *list) {
    char nama[CONTACT_NAMA_MAKS];
    char telp[CONTACT_TELP_MAKS];
    char email[CONTACT_EMAIL_MAKS];
    baca_baris("Nama  : ", nama, sizeof(nama));
    baca_baris("Telp  : ", telp, sizeof(telp));
    baca_baris("Email : ", email, sizeof(email));

    ContactStatus s = contact_tambah(list, nama, telp, email);
    switch (s) {
        case CONTACT_OK:
            printf("Kontak ditambahkan (id=%d).\n", list->data[list->jumlah - 1].id);
            break;
        case CONTACT_ERR_PENUH:
            printf("Daftar penuh.\n"); break;
        case CONTACT_ERR_INPUT_INVALID:
            printf("Input tidak valid (nama wajib diisi).\n"); break;
        default:
            printf("Error tidak dikenal.\n"); break;
    }
}

static void menu_ubah(ContactList *list) {
    int id;
    if (!baca_int("ID kontak yang diubah: ", &id)) {
        printf("ID tidak valid.\n"); return;
    }
    char nama[CONTACT_NAMA_MAKS];
    char telp[CONTACT_TELP_MAKS];
    char email[CONTACT_EMAIL_MAKS];
    baca_baris("Nama baru (kosongkan jika tidak diubah) : ", nama, sizeof(nama));
    baca_baris("Telp baru (kosongkan jika tidak diubah) : ", telp, sizeof(telp));
    baca_baris("Email baru (kosongkan jika tidak diubah): ", email, sizeof(email));

    ContactStatus s = contact_ubah(list, id,
                                    nama[0] ? nama : 0,
                                    telp[0] ? telp : 0,
                                    email[0] ? email : 0);
    if (s == CONTACT_OK)              printf("Kontak diubah.\n");
    else if (s == CONTACT_ERR_TIDAK_DITEMUKAN) printf("Kontak tidak ditemukan.\n");
    else                              printf("Input tidak valid.\n");
}

static void menu_hapus(ContactList *list) {
    int id;
    if (!baca_int("ID kontak yang dihapus: ", &id)) {
        printf("ID tidak valid.\n"); return;
    }
    ContactStatus s = contact_hapus(list, id);
    if (s == CONTACT_OK)              printf("Kontak dihapus.\n");
    else if (s == CONTACT_ERR_TIDAK_DITEMUKAN) printf("Kontak tidak ditemukan.\n");
}

static void menu_cari(const ContactList *list) {
    char nama[CONTACT_NAMA_MAKS];
    baca_baris("Nama yang dicari: ", nama, sizeof(nama));
    int idx = contact_cari(list, nama);
    if (idx < 0) {
        printf("Kontak dengan nama '%s' tidak ditemukan.\n", nama);
    } else {
        const Contact *c = &list->data[idx];
        printf("Ditemukan: [%d] %s | %s | %s\n",
               c->id, c->nama, c->telp, c->email);
    }
}

int main(void) {
    ContactList list;
    contact_list_init(&list);

    StorageStatus sm = storage_muat(&list, DB_PATH);
    if (sm == STORAGE_OK) {
        printf("Memuat %d kontak dari %s.\n", list.jumlah, DB_PATH);
    } else if (sm == STORAGE_ERR_BUKA_FILE) {
        printf("Belum ada file %s. Memulai dengan daftar kosong.\n", DB_PATH);
    } else {
        printf("Peringatan: format file rusak (kode %d).\n", sm);
    }

    int lanjut = 1;
    while (lanjut) {
        printf("\n=== Manajemen Kontak ===\n");
        printf("1. Tambah\n2. Tampilkan\n3. Cari\n4. Ubah\n5. Hapus\n6. Keluar\n");
        int pilihan = 0;
        if (!baca_int("Pilih: ", &pilihan)) { printf("Pilihan tidak valid.\n"); continue; }

        switch (pilihan) {
            case 1: menu_tambah(&list); break;
            case 2: contact_tampilkan(&list, stdout); break;
            case 3: menu_cari(&list); break;
            case 4: menu_ubah(&list); break;
            case 5: menu_hapus(&list); break;
            case 6: lanjut = 0; break;
            default: printf("Pilihan tidak dikenal.\n"); break;
        }
    }

    StorageStatus ss = storage_simpan(&list, DB_PATH);
    if (ss == STORAGE_OK) {
        printf("Menyimpan %d kontak ke %s.\n", list.jumlah, DB_PATH);
    } else {
        printf("Gagal menyimpan (kode %d).\n", ss);
    }
    printf("Terima kasih.\n");
    return 0;
}
