/* transaction.c - Implementasi model Transaction */
#include "transaction.h"

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

int transaction_date_is_valid(const char *date) {
    if (date == NULL) {
        return 0;
    }
    /* Format: YYYY-MM-DD = 10 karakter. */
    if (strlen(date) != 10) {
        return 0;
    }
    for (int i = 0; i < 10; i++) {
        char c = date[i];
        if (i == 4 || i == 7) {
            if (c != '-') {
                return 0;
            }
        } else {
            if (!isdigit((unsigned char)c)) {
                return 0;
            }
        }
    }
    /* Validasi rentang bulan dan hari secara kasar. */
    int y, m, d;
    if (sscanf(date, "%d-%d-%d", &y, &m, &d) != 3) {
        return 0;
    }
    if (y < 1900 || y > 2999) {
        return 0;
    }
    if (m < 1 || m > 12) {
        return 0;
    }
    if (d < 1 || d > 31) {
        return 0;
    }
    return 1;
}

int transaction_create(Transaction *t, int id, TxnType type,
                       double amount, const char *description,
                       const char *category, const char *date) {
    if (t == NULL || description == NULL || category == NULL || date == NULL) {
        return -1;
    }
    if (id <= 0) {
        return -2;
    }
    if (type != TXN_INCOME && type != TXN_EXPENSE) {
        return -3;
    }
    if (amount <= 0.0 || isnan(amount) || isinf(amount)) {
        return -4;
    }
    if (!transaction_date_is_valid(date)) {
        return -5;
    }

    t->id = id;
    t->type = type;
    t->amount = amount;
    strncpy(t->description, description, TXN_DESC_MAX - 1);
    t->description[TXN_DESC_MAX - 1] = '\0';
    strncpy(t->category, category, TXN_CATEGORY_MAX - 1);
    t->category[TXN_CATEGORY_MAX - 1] = '\0';
    strncpy(t->date, date, sizeof(t->date) - 1);
    t->date[sizeof(t->date) - 1] = '\0';
    return 0;
}

double transaction_signed_value(const Transaction *t) {
    if (t == NULL) {
        return 0.0;
    }
    return t->type * t->amount;
}

void transaction_print(const Transaction *t) {
    if (t == NULL) {
        printf("(null transaction)\n");
        return;
    }
    const char *sign = (t->type == TXN_INCOME) ? "+" : "-";
    const char *label = (t->type == TXN_INCOME) ? "MASUK " : "KELUAR";
    printf("[%04d] %s %s %s  Rp%12.2f  %s\n",
           t->id, t->date, label, t->category,
           t->type * t->amount, t->description);
    (void)sign;
}
