/* finance.c - Implementasi operasi Finance */
#include "finance.h"

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

void finance_init(Finance *f) {
    if (f == NULL) {
        return;
    }
    f->count = 0;
    f->next_id = 1;
}

/* Helper: case-insensitive string equality. */
static int eq_ci(const char *a, const char *b) {
    if (a == NULL || b == NULL) {
        return 0;
    }
    while (*a != '\0' && *b != '\0') {
        if (tolower((unsigned char)*a) != tolower((unsigned char)*b)) {
            return 0;
        }
        a++;
        b++;
    }
    return *a == '\0' && *b == '\0';
}

int finance_add(Finance *f, TxnType type, double amount,
                const char *description, const char *category,
                const char *date) {
    if (f == NULL || description == NULL || category == NULL || date == NULL) {
        return -1;
    }
    if (f->count >= FINANCE_CAPACITY) {
        return -1;
    }
    Transaction *slot = &f->items[f->count];
    int id = f->next_id;
    if (transaction_create(slot, id, type, amount, description,
                           category, date) != 0) {
        return -1;
    }
    f->next_id++;
    f->count++;
    return id;
}

int finance_delete(Finance *f, int id) {
    if (f == NULL) {
        return -1;
    }
    for (int i = 0; i < f->count; i++) {
        if (f->items[i].id == id) {
            memmove(&f->items[i], &f->items[i + 1],
                    (size_t)(f->count - i - 1) * sizeof(Transaction));
            f->count--;
            return 0;
        }
    }
    return -1;
}

int finance_filter_by_category(const Finance *f, const char *category,
                                Transaction *out, int out_cap) {
    if (f == NULL || out == NULL || out_cap <= 0) {
        return 0;
    }
    int found = 0;
    for (int i = 0; i < f->count && found < out_cap; i++) {
        if (eq_ci(f->items[i].category, category)) {
            out[found++] = f->items[i];
        }
    }
    return found;
}

int finance_filter_by_date(const Finance *f, const char *from,
                           const char *to, Transaction *out, int out_cap) {
    if (f == NULL || out == NULL || out_cap <= 0) {
        return 0;
    }
    int found = 0;
    for (int i = 0; i < f->count && found < out_cap; i++) {
        const char *d = f->items[i].date;
        if (from != NULL && strcmp(d, from) < 0) {
            continue;
        }
        if (to != NULL && strcmp(d, to) > 0) {
            continue;
        }
        out[found++] = f->items[i];
    }
    return found;
}

void finance_summary(const Finance *f, double *total_income,
                     double *total_expense, double *balance) {
    double inc = 0.0;
    double exp = 0.0;
    if (f != NULL) {
        for (int i = 0; i < f->count; i++) {
            if (f->items[i].type == TXN_INCOME) {
                inc += f->items[i].amount;
            } else {
                exp += f->items[i].amount;
            }
        }
    }
    if (total_income != NULL) {
        *total_income = inc;
    }
    if (total_expense != NULL) {
        *total_expense = exp;
    }
    if (balance != NULL) {
        *balance = inc - exp;
    }
}

void finance_print_all(const Finance *f) {
    if (f == NULL) {
        return;
    }
    printf("Total transaksi: %d/%d\n", f->count, FINANCE_CAPACITY);
    for (int i = 0; i < f->count; i++) {
        transaction_print(&f->items[i]);
    }
}
