/* main.c - Program utama Pengelola Keuangan Pribadi */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include "finance.h"
#include "storage.h"
#include "report.h"

#define DB_PATH "finance.csv"

static int read_line(char *buf, size_t cap) {
    if (fgets(buf, (int)cap, stdin) == NULL) {
        return -1;
    }
    size_t len = strlen(buf);
    while (len > 0 && (buf[len - 1] == '\n' || buf[len - 1] == '\r')) {
        buf[--len] = '\0';
    }
    return 0;
}

static void print_menu(void) {
    puts("");
    puts("=== Pengelola Keuangan Pribadi ===");
    puts("1. Catat pemasukan");
    puts("2. Catat pengeluaran");
    puts("3. Daftar semua transaksi");
    puts("4. Ringkasan keuangan");
    puts("5. Filter per kategori");
    puts("6. Filter per tanggal");
    puts("7. Laporan per kategori");
    puts("8. Laporan bulanan");
    puts("9. Hapus transaksi");
    puts("S. Simpan ke file");
    puts("L. Muat dari file");
    puts("Q. Keluar");
    printf("Pilihan: ");
}

static int ask_txn_type(TxnType wanted) {
    char buf[256];
    double amount;
    printf("Jumlah (Rp): ");
    if (read_line(buf, sizeof(buf)) != 0) {
        return -1;
    }
    amount = strtod(buf, NULL);
    if (amount <= 0) {
        printf("Jumlah harus positif.\n");
        return -1;
    }
    char desc[TXN_DESC_MAX];
    printf("Deskripsi: ");
    if (read_line(desc, sizeof(desc)) != 0) {
        return -1;
    }
    char cat[TXN_CATEGORY_MAX];
    printf("Kategori: ");
    if (read_line(cat, sizeof(cat)) != 0) {
        return -1;
    }
    char date[16];
    printf("Tanggal (YYYY-MM-DD, kosongkan = hari ini): ");
    if (read_line(date, sizeof(date)) != 0) {
        return -1;
    }
    if (date[0] == '\0') {
        strcpy(date, "2024-01-01");
    }
    int id = finance_add(NULL, wanted, 0, NULL, NULL, NULL);
    (void)id;
    return 0;
}

static void do_add(Finance *f, TxnType type) {
    char buf[256];
    printf("Jumlah (Rp): ");
    if (read_line(buf, sizeof(buf)) != 0) {
        return;
    }
    double amount = strtod(buf, NULL);
    if (amount <= 0) {
        printf("Jumlah harus positif.\n");
        return;
    }
    char desc[TXN_DESC_MAX];
    printf("Deskripsi: ");
    if (read_line(desc, sizeof(desc)) != 0) {
        return;
    }
    char cat[TXN_CATEGORY_MAX];
    printf("Kategori: ");
    if (read_line(cat, sizeof(cat)) != 0) {
        return;
    }
    char date[16];
    printf("Tanggal (YYYY-MM-DD): ");
    if (read_line(date, sizeof(date)) != 0) {
        return;
    }
    int id = finance_add(f, type, amount, desc, cat, date);
    if (id < 0) {
        printf("Gagal menambah transaksi. Periksa kembali input.\n");
        return;
    }
    printf("Transaksi dicatat dengan id=%d\n", id);
}

static void do_summary(const Finance *f) {
    double inc, exp, bal;
    finance_summary(f, &inc, &exp, &bal);
    printf("\n=== Ringkasan Keuangan ===\n");
    printf("Total pemasukan : Rp%12.2f\n", inc);
    printf("Total pengeluaran: Rp%12.2f\n", exp);
    printf("Saldo bersih    : Rp%12.2f\n", bal);
}

static void do_filter_category(const Finance *f) {
    char cat[TXN_CATEGORY_MAX];
    printf("Kategori: ");
    if (read_line(cat, sizeof(cat)) != 0) {
        return;
    }
    Transaction out[64];
    int n = finance_filter_by_category(f, cat, out, 64);
    printf("Ditemukan %d transaksi:\n", n);
    for (int i = 0; i < n; i++) {
        transaction_print(&out[i]);
    }
}

static void do_filter_date(const Finance *f) {
    char from[16], to[16];
    printf("Dari (YYYY-MM-DD): ");
    if (read_line(from, sizeof(from)) != 0) {
        return;
    }
    printf("Sampai (YYYY-MM-DD): ");
    if (read_line(to, sizeof(to)) != 0) {
        return;
    }
    Transaction out[64];
    int n = finance_filter_by_date(f, from, to, out, 64);
    printf("Ditemukan %d transaksi:\n", n);
    for (int i = 0; i < n; i++) {
        transaction_print(&out[i]);
    }
}

static void do_report_category(const Finance *f) {
    CategoryReport reports[32];
    int n = report_by_category(f, reports, 32);
    report_print_category(reports, n);
}

static void do_delete(Finance *f) {
    char buf[16];
    printf("Masukkan id transaksi: ");
    if (read_line(buf, sizeof(buf)) != 0) {
        return;
    }
    int id = (int)strtol(buf, NULL, 10);
    if (finance_delete(f, id) != 0) {
        printf("Transaksi id %d tidak ditemukan.\n", id);
        return;
    }
    printf("Transaksi id %d dihapus.\n", id);
}

int main(void) {
    Finance f;
    finance_init(&f);
    if (storage_load(&f, DB_PATH) > 0) {
        printf("Memuat %d transaksi dari %s\n", f.count, DB_PATH);
    }

    char choice[8];
    int running = 1;
    while (running) {
        print_menu();
        if (read_line(choice, sizeof(choice)) != 0) {
            break;
        }
        char c = (char)tolower((unsigned char)choice[0]);
        switch (c) {
            case '1': do_add(&f, TXN_INCOME); break;
            case '2': do_add(&f, TXN_EXPENSE); break;
            case '3': finance_print_all(&f); break;
            case '4': do_summary(&f); break;
            case '5': do_filter_category(&f); break;
            case '6': do_filter_date(&f); break;
            case '7': do_report_category(&f); break;
            case '8': report_print_monthly(&f); break;
            case '9': do_delete(&f); break;
            case 's': {
                int n = storage_save(&f, DB_PATH);
                if (n >= 0) {
                    printf("Menyimpan %d transaksi ke %s\n", n, DB_PATH);
                } else {
                    printf("Gagal menyimpan ke %s\n", DB_PATH);
                }
                break;
            }
            case 'l': {
                int n = storage_load(&f, DB_PATH);
                if (n >= 0) {
                    printf("Memuat %d transaksi dari %s\n", n, DB_PATH);
                } else {
                    printf("Gagal memuat dari %s\n", DB_PATH);
                }
                break;
            }
            case 'q': running = 0; break;
            default:  printf("Pilihan tidak dikenal: %c\n", c); break;
        }
    }
    /* Hindari warning unused function. */
    (void)ask_txn_type;
    puts("Terima kasih telah menggunakan Pengelola Keuangan.");
    return 0;
}
