/* main.c -- titik masuk aplikasi pengelola tugas. */

#include "task.h"
#include "storage.h"

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

#define DB_PATH "tugas.txt"

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(TaskList *list) {
    char judul[TASK_JUDUL_MAKS];
    char deskripsi[TASK_DESKRIPSI_MAKS];
    baca_baris("Judul      : ", judul, sizeof(judul));
    baca_baris("Deskripsi  : ", deskripsi, sizeof(deskripsi));
    int p = 0;
    if (!baca_int("Prioritas (1=Rendah,2=Sedang,3=Tinggi): ", &p)) {
        printf("Prioritas tidak valid.\n"); return;
    }
    TaskResult r = task_tambah(list, judul, deskripsi, (TaskPrioritas)p);
    if (r == TASK_OK) {
        printf("Tugas ditambahkan (id=%d).\n", list->data[list->jumlah - 1].id);
    } else {
        printf("Gagal menambah (kode %d).\n", r);
    }
}

static void menu_set_status(TaskList *list) {
    int id, s;
    if (!baca_int("ID tugas   : ", &id)) { printf("ID tidak valid.\n"); return; }
    if (!baca_int("Status (0=Belum,1=Proses,2=Selesai): ", &s)) {
        printf("Status tidak valid.\n"); return;
    }
    TaskResult r = task_set_status(list, id, (TaskStatus)s);
    if (r == TASK_OK) printf("Status diubah.\n");
    else if (r == TASK_ERR_TIDAK_DITEMUKAN) printf("Tugas tidak ditemukan.\n");
    else printf("Input tidak valid.\n");
}

static void menu_hapus(TaskList *list) {
    int id;
    if (!baca_int("ID tugas yang dihapus: ", &id)) { printf("ID tidak valid.\n"); return; }
    TaskResult r = task_hapus(list, id);
    if (r == TASK_OK) printf("Tugas dihapus.\n");
    else if (r == TASK_ERR_TIDAK_DITEMUKAN) printf("Tugas tidak ditemukan.\n");
}

static void menu_filter(const TaskList *list) {
    int s;
    if (!baca_int("Filter status (0=Belum,1=Proses,2=Selesai): ", &s)) {
        printf("Status tidak valid.\n"); return;
    }
    if (s < TASK_STATUS_BELUM || s > TASK_STATUS_SELESAI) {
        printf("Status tidak valid.\n"); return;
    }
    task_filter_status(list, (TaskStatus)s, stdout);
}

static void menu_cari(const TaskList *list) {
    char kata[TASK_JUDUL_MAKS];
    baca_baris("Kata kunci judul: ", kata, sizeof(kata));
    int idx = task_cari(list, kata);
    if (idx < 0) {
        printf("Tidak ada tugas dengan judul mengandung '%s'.\n", kata);
    } else {
        const Task *t = &list->data[idx];
        printf("Ditemukan: [%d] %s | %s | %s\n",
               t->id, t->judul,
               task_status_nama(t->status),
               task_prioritas_nama(t->prioritas));
    }
}

int main(void) {
    TaskList list;
    task_list_init(&list);

    StorageStatus sm = storage_muat(&list, DB_PATH);
    if (sm == STORAGE_OK) {
        printf("Memuat %d tugas 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=== Pengelola Tugas ===\n");
        printf("1. Tambah\n2. Tampilkan\n3. Filter status\n");
        printf("4. Cari judul\n5. Set status\n6. Hapus\n7. 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: task_tampilkan(&list, stdout); break;
            case 3: menu_filter(&list); break;
            case 4: menu_cari(&list); break;
            case 5: menu_set_status(&list); break;
            case 6: menu_hapus(&list); break;
            case 7: lanjut = 0; break;
            default: printf("Pilihan tidak dikenal.\n"); break;
        }
    }

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