/*
 * ac_weekroll_batch.pgc - ac 주간 가맹점 집계 롤업 배치 (INSERT..SELECT, XA).
 *
 * ATMI client: 기준일 포함 직전 7일 매입을 가맹점별로 롤업해 기준일 키의
 * merchant_summary 로 밀어넣는다(ON CONFLICT 갱신). 반영 행수와 주간
 * 총액을 되읽어 보고한다.
 * Usage: ac_weekroll_batch [YYYY-MM-DD]
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <atmi.h>
#include "ac_weekroll_batch.h"

int main(int argc, char **argv)
{
    ac_weekroll_ctx_t cx;
    const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";

    EXEC SQL BEGIN DECLARE SECTION;
    char h_bizdate[16];
    long h_gross = 0;
    EXEC SQL END DECLARE SECTION;

    memset(&cx, 0, sizeof(cx));
    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(120, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }

    /* 주간 롤업: 직전 7일 → 기준일 키 upsert */
    EXEC SQL INSERT INTO merchant_summary (merchant_id, biz_date, txn_count, gross_amount, fee_amount, net_amount, updated_at)
        SELECT merchant_id, CAST(:h_bizdate AS date), count(*), sum(amount), sum(fee), sum(net), now()
        FROM purchase
        WHERE biz_date > CAST(:h_bizdate AS date) - 7
          AND biz_date <= CAST(:h_bizdate AS date)
          AND status NOT IN ('C', 'V', 'P')
        GROUP BY merchant_id
        ON CONFLICT (merchant_id, biz_date) DO UPDATE
           SET txn_count = EXCLUDED.txn_count,
               gross_amount = EXCLUDED.gross_amount,
               fee_amount = EXCLUDED.fee_amount,
               net_amount = EXCLUDED.net_amount,
               updated_at = now();
    if (sqlca.sqlcode < 0) { fprintf(stderr, "ac_weekroll_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
    cx.rolled = sqlca.sqlerrd[2];

    /* 반영 결과 되읽기 */
    EXEC SQL SELECT coalesce(sum(gross_amount), 0) INTO :h_gross
        FROM merchant_summary WHERE biz_date = CAST(:h_bizdate AS date);
    if (sqlca.sqlcode < 0) { fprintf(stderr, "readback FAIL [%d]\n", sqlca.sqlcode); tpabort(0); return 1; }
    cx.week_gross = h_gross;

    if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
    printf(">>> ac_weekroll_batch COMMIT: base=%s rolled=%ld week_gross=%ld\n",
           bizdate, cx.rolled, cx.week_gross);

    tpclose(); tpterm();
    return 0;
}
