/*
 * st_slabfee_batch.pgc - 슬라브(누진 구간) 요율 배치 (XA 배치).
 * 당일 매입 총액을 기준으로 MDR 요율표의 구간을 커서로 순회하며, 금액이 각 구간에
 * 걸치는 부분에만 해당 요율을 적용하는 누진(슬라브) 방식으로 예상 수수료를 합산한다.
 * 사용법: st_slabfee_batch [YYYY-MM-DD]
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <atmi.h>
#include "st_dbio.h"
#include "st_slabfee_batch.h"

int main(int argc, char **argv)
{
    const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
    st_slabfee_rec_t rec;
    long prev_min = -1, prev_bps = 0;
    memset(&rec, 0, sizeof(rec));
    EXEC SQL BEGIN DECLARE SECTION;
    char h_bizdate[16];
    long h_gross, h_min, h_bps;
    EXEC SQL END DECLARE SECTION;

    strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;

    if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
    if (tpopen() < 0)     { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
    if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }

    EXEC SQL SELECT coalesce(sum(amount),0) INTO :h_gross FROM purchase WHERE biz_date = :h_bizdate;
    if (sqlca.sqlcode < 0) { fprintf(stderr, "GROSS FAIL [%d]\n", sqlca.sqlcode); tpabort(0); return 1; }
    rec.day_gross = h_gross;

    EXEC SQL DECLARE slabfee_bc CURSOR FOR
        SELECT band_min, rate_bps FROM st_fee_rate WHERE fee_type = 'MDR' ORDER BY band_min;
    EXEC SQL OPEN slabfee_bc;
    if (sqlca.sqlcode < 0) { fprintf(stderr, "OPEN FAIL [%d]\n", sqlca.sqlcode); tpabort(0); return 1; }
    for (;;) {
        EXEC SQL FETCH slabfee_bc INTO :h_min, :h_bps;
        if (sqlca.sqlcode == 100) break;
        if (sqlca.sqlcode < 0) { EXEC SQL CLOSE slabfee_bc; tpabort(0); return 1; }
        if (prev_min >= 0 && h_gross > prev_min) {
            long top = (h_gross < h_min) ? h_gross : h_min;
            long seg = (top - prev_min) * prev_bps / 10000;
            rec.slab_fee += seg; rec.segs++;
            printf("    SLAB [%ld,%ld) bps=%ld -> %ld\n", prev_min, h_min, prev_bps, seg);
        }
        prev_min = h_min; prev_bps = h_bps;
    }
    EXEC SQL CLOSE slabfee_bc;
    if (prev_min >= 0 && h_gross > prev_min) {
        long seg = (h_gross - prev_min) * prev_bps / 10000;
        rec.slab_fee += seg; rec.segs++;
    }

    if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
    printf(">>> %s COMMIT: bizdate=%s gross=%ld segs=%ld slab_fee=%ld\n",
           ST_SLABFEE_TAG, bizdate, rec.day_gross, rec.segs, rec.slab_fee);
    tpclose(); tpterm();
    return 0;
}
