/* storage.c - Implementasi persistensi CSV */
#include "storage.h"

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

/* Helper: trim newline dari akhir string hasil fgets. */
static void strip_newline(char *s) {
    size_t len = strlen(s);
    while (len > 0 && (s[len - 1] == '\n' || s[len - 1] == '\r')) {
        s[--len] = '\0';
    }
}

/* Helper: parse satu baris CSV "id,name,price,stock".
 * Mengembalikan 1 bila sukses, 0 bila format tidak valid. */
static int parse_line(const char *line, int *id, char *name,
                      size_t name_cap, double *price, int *stock) {
    /* %n menyimpan jumlah karakter yang sudah diproses.
     * Kita pisahkan field dengan pemisah koma. */
    int consumed = 0;
    int items = sscanf(line, "%d,%63[^,],%lf,%d%n",
                       id, name, price, stock, &consumed);
    if (items != 4) {
        return 0;
    }
    /* Pastikan tidak ada karakter asing di akhir baris. */
    char trailing = line[consumed];
    if (trailing != '\0' && trailing != '\n' && trailing != '\r') {
        return 0;
    }
    if (name_cap < PRODUCT_NAME_MAX) {
        return 0;
    }
    return 1;
}

int storage_save(const Inventory *inv, const char *path) {
    if (inv == NULL || path == NULL) {
        return -1;
    }
    FILE *fp = fopen(path, "w");
    if (fp == NULL) {
        return -1;
    }

    /* Tulis header komentar agar mudah diperiksa manusia. */
    fprintf(fp, "# id,name,price,stock\n");
    int written = 0;
    for (int i = 0; i < inv->count; i++) {
        const Product *p = &inv->items[i];
        /* Gunakan format yang stabil: id 6 digit, harga 2 desimal. */
        int n = fprintf(fp, "%d,%s,%.2f,%d\n",
                        p->id, p->name, p->price, p->stock);
        if (n < 0) {
            fclose(fp);
            return -1;
        }
        written++;
    }
    fclose(fp);
    return written;
}

int storage_load(Inventory *inv, const char *path) {
    if (inv == NULL || path == NULL) {
        return -1;
    }
    FILE *fp = fopen(path, "r");
    if (fp == NULL) {
        return -1;
    }

    inventory_init(inv);

    char line[256];
    int read = 0;
    int max_id_seen = 0;
    while (fgets(line, sizeof(line), fp) != NULL) {
        /* Lewati baris kosong dan komentar. */
        if (line[0] == '#' || line[0] == '\n' || line[0] == '\r') {
            continue;
        }
        strip_newline(line);

        int id;
        char name[PRODUCT_NAME_MAX];
        double price;
        int stock;
        if (!parse_line(line, &id, name, sizeof(name), &price, &stock)) {
            continue;
        }
        if (inv->count >= INVENTORY_CAPACITY) {
            break;
        }
        Product *slot = &inv->items[inv->count];
        if (product_create(slot, id, name, price, stock) != 0) {
            continue;
        }
        if (id > max_id_seen) {
            max_id_seen = id;
        }
        inv->count++;
        read++;
    }
    inv->next_id = max_id_seen + 1;
    fclose(fp);
    return read;
}
