/* task.c -- implementasi model dan operasi tugas. */

#include "task.h"

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

void task_list_init(TaskList *list) {
    if (list == 0) return;
    list->jumlah = 0;
    list->id_berikutnya = 1;
}

int task_valid_judul(const char *judul) {
    if (judul == 0 || judul[0] == '\0') return 0;
    if (strlen(judul) >= TASK_JUDUL_MAKS) return 0;
    return 1;
}

int task_valid_prioritas(int p) {
    return p == TASK_PRIORITAS_RENDAH
        || p == TASK_PRIORITAS_SEDANG
        || p == TASK_PRIORITAS_TINGGI;
}

TaskResult task_tambah(TaskList *list,
                       const char *judul,
                       const char *deskripsi,
                       TaskPrioritas prioritas) {
    if (list == 0) return TASK_ERR_INPUT_INVALID;
    if (!task_valid_judul(judul)) return TASK_ERR_INPUT_INVALID;
    if (!task_valid_prioritas((int)prioritas)) return TASK_ERR_INPUT_INVALID;
    if (list->jumlah >= TASK_MAKS) return TASK_ERR_PENUH;

    Task *t = &list->data[list->jumlah];
    t->id = list->id_berikutnya++;
    strncpy(t->judul, judul, TASK_JUDUL_MAKS - 1);
    t->judul[TASK_JUDUL_MAKS - 1] = '\0';
    strncpy(t->deskripsi, deskripsi ? deskripsi : "", TASK_DESKRIPSI_MAKS - 1);
    t->deskripsi[TASK_DESKRIPSI_MAKS - 1] = '\0';
    t->status = TASK_STATUS_BELUM;
    t->prioritas = prioritas;
    list->jumlah++;
    return TASK_OK;
}

void task_tampilkan(const TaskList *list, FILE *out) {
    if (list == 0 || out == 0) return;
    fprintf(out, "%-4s %-30s %-12s %-10s\n",
            "ID", "Judul", "Status", "Prioritas");
    for (int i = 0; i < list->jumlah; i++) {
        const Task *t = &list->data[i];
        fprintf(out, "%-4d %-30s %-12s %-10s\n",
                t->id, t->judul,
                task_status_nama(t->status),
                task_prioritas_nama(t->prioritas));
    }
    fprintf(out, "Total: %d tugas\n", list->jumlah);
}

TaskResult task_set_status(TaskList *list, int id, TaskStatus status) {
    if (list == 0) return TASK_ERR_INPUT_INVALID;
    if (status < TASK_STATUS_BELUM || status > TASK_STATUS_SELESAI) {
        return TASK_ERR_INPUT_INVALID;
    }
    for (int i = 0; i < list->jumlah; i++) {
        if (list->data[i].id == id) {
            list->data[i].status = status;
            return TASK_OK;
        }
    }
    return TASK_ERR_TIDAK_DITEMUKAN;
}

TaskResult task_hapus(TaskList *list, int id) {
    if (list == 0) return TASK_ERR_INPUT_INVALID;
    for (int i = 0; i < list->jumlah; i++) {
        if (list->data[i].id == id) {
            for (int j = i; j < list->jumlah - 1; j++) {
                list->data[j] = list->data[j + 1];
            }
            list->jumlah--;
            return TASK_OK;
        }
    }
    return TASK_ERR_TIDAK_DITEMUKAN;
}

int task_filter_status(const TaskList *list, TaskStatus status, FILE *out) {
    if (list == 0 || out == 0) return 0;
    int count = 0;
    fprintf(out, "%-4s %-30s %-12s %-10s\n",
            "ID", "Judul", "Status", "Prioritas");
    for (int i = 0; i < list->jumlah; i++) {
        const Task *t = &list->data[i];
        if (t->status == status) {
            fprintf(out, "%-4d %-30s %-12s %-10s\n",
                    t->id, t->judul,
                    task_status_nama(t->status),
                    task_prioritas_nama(t->prioritas));
            count++;
        }
    }
    fprintf(out, "Ditemukan: %d tugas\n", count);
    return count;
}

int task_cari(const TaskList *list, const char *kata_kunci) {
    if (list == 0 || kata_kunci == 0) return -1;
    for (int i = 0; i < list->jumlah; i++) {
        if (strstr(list->data[i].judul, kata_kunci) != 0) {
            return i;
        }
    }
    return -1;
}

const char *task_status_nama(TaskStatus s) {
    switch (s) {
        case TASK_STATUS_BELUM:  return "Belum";
        case TASK_STATUS_PROSES: return "Proses";
        case TASK_STATUS_SELESAI:return "Selesai";
        default:                 return "?";
    }
}

const char *task_prioritas_nama(TaskPrioritas p) {
    switch (p) {
        case TASK_PRIORITAS_RENDAH: return "Rendah";
        case TASK_PRIORITAS_SEDANG: return "Sedang";
        case TASK_PRIORITAS_TINGGI: return "Tinggi";
        default:                     return "?";
    }
}
