/*
 * py_bankfile_batch.pgc - py 은행별 지급파일 일괄 생성 배치 (커서 + 파일편성, XA).
 *
 * 당일 승인(A) 지급건의 은행코드를 DISTINCT 커서로 훑어, 은행마다 py_file
 * 헤더를 만들고 해당 은행 건을 파일편성(F)+file_id 로 전이한다. ONE XA txn.
 * host 변수는 전용 카피북 py_bankfile_cpy.h 를 EXEC SQL INCLUDE.
 * Usage: py_bankfile_batch [YYYY-MM-DD]
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <atmi.h>

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

    EXEC SQL INCLUDE py_bankfile_cpy;

    strncpy(c_bizdate, bizdate, sizeof(c_bizdate)-1); c_bizdate[sizeof(c_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; }

    EXEC SQL DECLARE pbf CURSOR FOR
        SELECT DISTINCT a.bank_code
          FROM py_payout p JOIN py_account a ON p.account_no = a.account_no
         WHERE p.biz_date = :c_bizdate AND p.status = 'A'
         ORDER BY a.bank_code;
    EXEC SQL OPEN pbf;
    if (sqlca.sqlcode < 0) { fprintf(stderr, "OPEN FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }

    for (;;) {
        EXEC SQL FETCH pbf INTO :c_bank;
        if (sqlca.sqlcode == 100) break;
        if (sqlca.sqlcode < 0) { fprintf(stderr, "FETCH FAIL [%d]\n", sqlca.sqlcode); EXEC SQL CLOSE pbf; tpabort(0); return 1; }

        EXEC SQL SELECT count(*), coalesce(sum(p.net),0) INTO :c_cnt, :c_sum
            FROM py_payout p JOIN py_account a ON p.account_no = a.account_no
            WHERE p.biz_date = :c_bizdate AND p.status = 'A' AND a.bank_code = :c_bank;
        if (sqlca.sqlcode < 0 || c_cnt == 0) continue;

        snprintf(c_fname, sizeof(c_fname), "PAYOUT_%s_%s.dat", c_bank, c_bizdate);
        EXEC SQL SELECT nextval('py_file_seq') INTO :c_fid;
        if (sqlca.sqlcode < 0) { EXEC SQL CLOSE pbf; tpabort(0); return 1; }
        EXEC SQL INSERT INTO py_file (file_id, biz_date, file_name, record_count, total_amount, status)
            VALUES (:c_fid, :c_bizdate, :c_fname, :c_cnt, :c_sum, 'G');
        if (sqlca.sqlcode < 0) { EXEC SQL CLOSE pbf; tpabort(0); return 1; }
        EXEC SQL UPDATE py_payout SET status = 'F', file_id = :c_fid, updated_at = now()
            FROM py_account a
            WHERE py_payout.account_no = a.account_no AND py_payout.biz_date = :c_bizdate
              AND py_payout.status = 'A' AND a.bank_code = :c_bank;
        if (sqlca.sqlcode < 0) { EXEC SQL CLOSE pbf; tpabort(0); return 1; }
        files++; recs += c_cnt;
        printf("  은행 %s: 파일 %ld 생성 (%ld건 / %ld원)\n", c_bank, c_fid, c_cnt, c_sum);
    }
    EXEC SQL CLOSE pbf;

    if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
    printf(">>> py_bankfile_batch COMMIT: bizdate=%s files=%ld recs=%ld\n", bizdate, files, recs);

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