/* report.c - Implementasi laporan keuangan */
#include "report.h"

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

static int eq_ci(const char *a, const char *b) {
    while (*a != '\0' && *b != '\0') {
        if (tolower((unsigned char)*a) != tolower((unsigned char)*b)) {
            return 0;
        }
        a++;
        b++;
    }
    return *a == '\0' && *b == '\0';
}

static void cat_report_init(CategoryReport *r, const char *category) {
    memset(r, 0, sizeof(*r));
    strncpy(r->category, category, TXN_CATEGORY_MAX - 1);
    r->category[TXN_CATEGORY_MAX - 1] = '\0';
}

int report_by_category(const Finance *f, CategoryReport *out, int out_cap) {
    if (f == NULL || out == NULL || out_cap <= 0) {
        return 0;
    }
    int unique = 0;
    for (int i = 0; i < f->count; i++) {
        const Transaction *t = &f->items[i];
        /* Cari kategori yang sudah ada di `out`. */
        int found = -1;
        for (int k = 0; k < unique; k++) {
            if (eq_ci(out[k].category, t->category)) {
                found = k;
                break;
            }
        }
        if (found < 0) {
            if (unique >= out_cap) {
                continue;
            }
            cat_report_init(&out[unique], t->category);
            found = unique;
            unique++;
        }
        if (t->type == TXN_INCOME) {
            out[found].income += t->amount;
        } else {
            out[found].expense += t->amount;
        }
        out[found].balance += transaction_signed_value(t);
        out[found].count++;
    }
    return unique;
}

void report_print_category(const CategoryReport *r, int count) {
    if (r == NULL || count <= 0) {
        printf("Tidak ada data untuk laporan.\n");
        return;
    }
    printf("\n=== Laporan per Kategori ===\n");
    printf("%-20s %12s %12s %12s  %6s\n",
           "Kategori", "Pemasukan", "Pengeluaran", "Saldo", "#Txn");
    double total_inc = 0, total_exp = 0;
    for (int i = 0; i < count; i++) {
        printf("%-20s %12.2f %12.2f %12.2f  %6d\n",
               r[i].category, r[i].income, r[i].expense,
               r[i].balance, r[i].count);
        total_inc += r[i].income;
        total_exp += r[i].expense;
    }
    printf("%-20s %12.2f %12.2f %12.2f\n",
           "TOTAL", total_inc, total_exp, total_inc - total_exp);
}

void report_print_monthly(const Finance *f) {
    if (f == NULL || f->count == 0) {
        printf("Tidak ada data untuk laporan bulanan.\n");
        return;
    }
    printf("\n=== Laporan Bulanan ===\n");
    printf("%-8s %12s %12s %12s\n",
           "Bulan", "Pemasukan", "Pengeluaran", "Saldo");

    char current[8] = "";
    double m_inc = 0, m_exp = 0;
    for (int i = 0; i < f->count; i++) {
        const Transaction *t = &f->items[i];
        char month[8];
        /* YYYY-MM diambil dari 7 karakter pertama date. */
        snprintf(month, sizeof(month), "%.7s", t->date);
        if (strcmp(month, current) != 0) {
            if (current[0] != '\0') {
                printf("%-8s %12.2f %12.2f %12.2f\n",
                       current, m_inc, m_exp, m_inc - m_exp);
            }
            strcpy(current, month);
            m_inc = 0;
            m_exp = 0;
        }
        if (t->type == TXN_INCOME) {
            m_inc += t->amount;
        } else {
            m_exp += t->amount;
        }
    }
    if (current[0] != '\0') {
        printf("%-8s %12.2f %12.2f %12.2f\n",
               current, m_inc, m_exp, m_inc - m_exp);
    }
}
