/* inventory.c - Implementasi operasi CRUD Inventory */
#include "inventory.h"

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

void inventory_init(Inventory *inv) {
    if (inv == NULL) {
        return;
    }
    inv->count = 0;
    inv->next_id = 1;
    /* Tidak perlu zero-initialize array items karena count = 0. */
}

int inventory_add(Inventory *inv, const char *name,
                  double price, int stock) {
    if (inv == NULL || name == NULL) {
        return -1;
    }
    if (inv->count >= INVENTORY_CAPACITY) {
        return -1;
    }

    Product *slot = &inv->items[inv->count];
    int id = inv->next_id;
    int rc = product_create(slot, id, name, price, stock);
    if (rc != 0) {
        return -1;
    }
    inv->next_id++;
    inv->count++;
    return id;
}

Product *inventory_find_by_id(Inventory *inv, int id) {
    if (inv == NULL) {
        return NULL;
    }
    for (int i = 0; i < inv->count; i++) {
        if (inv->items[i].id == id) {
            return &inv->items[i];
        }
    }
    return NULL;
}

/* Helper: case-insensitive substring match.
 * Mengembalikan 1 bila `needle` muncul di `haystack`. */
static int contains_ci(const char *haystack, const char *needle) {
    if (needle == NULL || needle[0] == '\0') {
        return 1; /* keyword kosong = match semua */
    }
    if (haystack == NULL) {
        return 0;
    }
    /* Iterasi setiap posisi awal di haystack. */
    for (const char *h = haystack; *h != '\0'; h++) {
        const char *hi = h;
        const char *ni = needle;
        while (*hi != '\0' && *ni != '\0' &&
               tolower((unsigned char)*hi) == tolower((unsigned char)*ni)) {
            hi++;
            ni++;
        }
        if (*ni == '\0') {
            return 1;
        }
    }
    return 0;
}

int inventory_find_by_name(Inventory *inv, const char *keyword,
                           Product *out, int out_cap) {
    if (inv == NULL || out == NULL || out_cap <= 0) {
        return 0;
    }
    int found = 0;
    for (int i = 0; i < inv->count && found < out_cap; i++) {
        if (contains_ci(inv->items[i].name, keyword)) {
            out[found++] = inv->items[i];
        }
    }
    return found;
}

int inventory_update(Inventory *inv, int id,
                     double new_price, int new_stock) {
    Product *p = inventory_find_by_id(inv, id);
    if (p == NULL) {
        return -1;
    }
    if (new_price < 0.0 || new_stock < 0) {
        return -1;
    }
    p->price = new_price;
    p->stock = new_stock;
    return 0;
}

int inventory_delete(Inventory *inv, int id) {
    if (inv == NULL) {
        return -1;
    }
    for (int i = 0; i < inv->count; i++) {
        if (inv->items[i].id == id) {
            /* Geser elemen setelahnya ke kiri (swap dengan elemen terakhir
             * bisa mengacaukan urutan, jadi kita pakai memmove). */
            memmove(&inv->items[i], &inv->items[i + 1],
                    (size_t)(inv->count - i - 1) * sizeof(Product));
            inv->count--;
            return 0;
        }
    }
    return -1;
}

/* Helper: tukar dua Product. */
static void swap_product(Product *a, Product *b) {
    Product tmp = *a;
    *a = *b;
    *b = tmp;
}

void inventory_sort_by_name(Inventory *inv) {
    if (inv == NULL || inv->count < 2) {
        return;
    }
    /* Bubble sort: sederhana, cukup untuk kapasitas kecil. */
    for (int i = 0; i < inv->count - 1; i++) {
        for (int j = 0; j < inv->count - i - 1; j++) {
            if (strcmp(inv->items[j].name,
                       inv->items[j + 1].name) > 0) {
                swap_product(&inv->items[j], &inv->items[j + 1]);
            }
        }
    }
}

void inventory_sort_by_price(Inventory *inv) {
    if (inv == NULL || inv->count < 2) {
        return;
    }
    for (int i = 0; i < inv->count - 1; i++) {
        for (int j = 0; j < inv->count - i - 1; j++) {
            if (inv->items[j].price > inv->items[j + 1].price) {
                swap_product(&inv->items[j], &inv->items[j + 1]);
            }
        }
    }
}

void inventory_print_all(const Inventory *inv) {
    if (inv == NULL) {
        return;
    }
    printf("Total produk: %d/%d\n", inv->count, INVENTORY_CAPACITY);
    for (int i = 0; i < inv->count; i++) {
        product_print(&inv->items[i]);
    }
}
