/*
 * lg_periodtb_batch.pgc - lg 기간별 시산표 배치 (INSERT..SELECT + XA).
 *
 * [FROM ~ TO] 구간 원장 라인을 계정별로 집계해 기말일(TO) 키로 lg_trial_bal
 * 에 세트 지향 한 방(INSERT..SELECT..ON CONFLICT)으로 적재한 뒤, 적재 결과를
 * 재조회해 총차변=총대변 균형을 검증한다. ONE global XA transaction.
 * Usage: lg_periodtb_batch [FROM] [TO]
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <atmi.h>
#include "lg_dbio.h"
#include "lg_periodtb_batch.h"

int main(int argc, char **argv)
{
    lg_periodtb_rec_t rec;

    EXEC SQL BEGIN DECLARE SECTION;
    char h_from[16], h_to[16];
    long h_rows, h_dr, h_cr;
    EXEC SQL END DECLARE SECTION;

    memset(&rec, 0, sizeof(rec));
    strncpy(rec.date_from, (argc > 1) ? argv[1] : "2026-07-01", sizeof(rec.date_from)-1);
    strncpy(rec.date_to,   (argc > 2) ? argv[2] : "2026-07-19", sizeof(rec.date_to)-1);
    strncpy(h_from, rec.date_from, sizeof(h_from)-1); h_from[sizeof(h_from)-1] = 0;
    strncpy(h_to, rec.date_to, sizeof(h_to)-1); h_to[sizeof(h_to)-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 INSERT INTO lg_trial_bal (acct, biz_date, debit_total, credit_total, diff)
        SELECT acct, CAST(:h_to AS date),
               coalesce(sum(CASE WHEN dc = 'D' THEN amount ELSE 0 END), 0),
               coalesce(sum(CASE WHEN dc = 'C' THEN amount ELSE 0 END), 0),
               coalesce(sum(CASE WHEN dc = 'D' THEN amount ELSE -amount END), 0)
        FROM lg_ledger_line
        WHERE biz_date >= :h_from AND biz_date <= :h_to
        GROUP BY acct
        ON CONFLICT (acct, biz_date) DO UPDATE
        SET debit_total = EXCLUDED.debit_total, credit_total = EXCLUDED.credit_total,
            diff = EXCLUDED.diff, updated_at = now();
    if (sqlca.sqlcode < 0) { fprintf(stderr, "LOAD FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
    h_rows = sqlca.sqlerrd[2];

    EXEC SQL SELECT coalesce(sum(debit_total), 0), coalesce(sum(credit_total), 0)
        INTO :h_dr, :h_cr FROM lg_trial_bal WHERE biz_date = :h_to;
    if (sqlca.sqlcode < 0) { fprintf(stderr, "VERIFY FAIL [%d]\n", sqlca.sqlcode); tpabort(0); return 1; }

    if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
    rec.accts = h_rows; rec.dr_total = h_dr; rec.cr_total = h_cr;
    printf(">>> lg_periodtb_batch COMMIT: [%s~%s] %ld계정 차변 %ld 대변 %ld %s\n",
           rec.date_from, rec.date_to, rec.accts, rec.dr_total, rec.cr_total,
           (rec.dr_total == rec.cr_total) ? "(균형)" : "(불균형!)");

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