/*
 * cl_finalize_batch.pgc - cl 가마감 -> 본마감 일괄 확정 배치 (커서 + 재집계 + XA).
 *
 * 월 내 가마감(PROV, status O)을 커서로 순회하며 각 일자의 매입을 재집계해
 * 본마감(C, memo FINAL)으로 확정한다. 가마감 대비 건수 변동은 리포트로 출력.
 * 전 구간 ONE global XA. host 변수는 전용 카피북 cl_finalize_cpy.h 사용.
 * Usage: cl_finalize_batch [YYYY-MM]
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <atmi.h>

int main(int argc, char **argv)
{
    const char *month = (argc > 1) ? argv[1] : "2026-07";
    long fixed = 0, drift = 0;

    EXEC SQL INCLUDE cl_finalize_cpy;

    strncpy(fz_month, month, sizeof(fz_month)-1); fz_month[sizeof(fz_month)-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(90, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }

    EXEC SQL DECLARE bfin CURSOR FOR
        SELECT close_id, period_key, txn_count FROM cl_close_log
        WHERE close_type = 'DAILY' AND status = 'O' AND memo = 'PROV'
          AND period_key LIKE :fz_month || '%'
        ORDER BY period_key;
    EXEC SQL OPEN bfin;
    if (sqlca.sqlcode < 0) { fprintf(stderr, "OPEN FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }

    for (;;) {
        EXEC SQL FETCH bfin INTO :fz_cid, :fz_day, :fz_oldcnt;
        if (sqlca.sqlcode == 100) break;
        if (sqlca.sqlcode < 0) { EXEC SQL CLOSE bfin; tpabort(0); return 1; }
        EXEC SQL SELECT count(*), coalesce(sum(amount),0) INTO :fz_cnt, :fz_amt
            FROM purchase WHERE biz_date = :fz_day AND status IN ('M','S');
        if (sqlca.sqlcode < 0) { EXEC SQL CLOSE bfin; tpabort(0); return 1; }
        EXEC SQL UPDATE cl_close_log
            SET status = 'C', txn_count = :fz_cnt, total_amount = :fz_amt,
                memo = 'FINAL', updated_at = now()
            WHERE close_id = :fz_cid AND status = 'O';
        if (sqlca.sqlcode < 0) { EXEC SQL CLOSE bfin; tpabort(0); return 1; }
        if (fz_cnt != fz_oldcnt) {
            printf("    본마감 %s cid=%ld 건수변동 %ld -> %ld\n", fz_day, fz_cid, fz_oldcnt, fz_cnt);
            drift++;
        }
        fixed++;
    }
    EXEC SQL CLOSE bfin;

    if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
    printf(">>> cl_finalize_batch COMMIT: %s 본마감 확정=%ld건 (변동 %ld건)\n", month, fixed, drift);

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