/*
 * lg_closechk_batch.pgc - lg 결산 체크리스트 배치 (XA).
 *
 * 결산 직전 점검 4항목을 순서대로 수행해 체크리스트를 출력한다:
 *  [1] 미결(D) 전표  [2] 차변합<>대변합 불균형 전표  [3] 0원 라인
 *  [4] 헤더 없는 고아 라인. 실패 항목 수를 exit code 로 반영하지 않고
 * 리포트만 남긴다(운영 판단용). ONE global XA transaction 에서 수행.
 * Usage: lg_closechk_batch [YYYY-MM-DD]
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <atmi.h>
#include "lg_dbio.h"
#include "lg_closechk_batch.h"

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

    EXEC SQL BEGIN DECLARE SECTION;
    char h_bizdate[16];
    long h_n1, h_n2, h_n3, h_n4;
    EXEC SQL END DECLARE SECTION;

    memset(&rec, 0, sizeof(rec));
    strncpy(rec.biz_date, (argc > 1) ? argv[1] : "2026-07-19", sizeof(rec.biz_date)-1);
    strncpy(h_bizdate, rec.biz_date, 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 count(*) INTO :h_n1
        FROM lg_voucher WHERE biz_date = :h_bizdate AND status = 'D';
    if (sqlca.sqlcode < 0) { tpabort(0); return 1; }

    EXEC SQL SELECT count(*) INTO :h_n2 FROM (
        SELECT voucher_id FROM lg_ledger_line WHERE biz_date = :h_bizdate
        GROUP BY voucher_id
        HAVING sum(CASE WHEN dc = 'D' THEN amount ELSE -amount END) <> 0) q;
    if (sqlca.sqlcode < 0) { tpabort(0); return 1; }

    EXEC SQL SELECT count(*) INTO :h_n3
        FROM lg_ledger_line WHERE biz_date = :h_bizdate AND amount = 0;
    if (sqlca.sqlcode < 0) { tpabort(0); return 1; }

    EXEC SQL SELECT count(*) INTO :h_n4
        FROM lg_ledger_line l
        WHERE l.biz_date = :h_bizdate
          AND NOT EXISTS (SELECT 1 FROM lg_voucher v WHERE v.voucher_id = l.voucher_id);
    if (sqlca.sqlcode < 0) { tpabort(0); return 1; }

    if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }

    rec.draft_vouchers = h_n1; rec.imbalanced = h_n2;
    rec.zero_lines = h_n3;     rec.orphan_lines = h_n4;
    rec.failed_items = (h_n1 > 0) + (h_n2 > 0) + (h_n3 > 0) + (h_n4 > 0);

    printf("--- 결산 체크리스트 (%s) ---\n", rec.biz_date);
    printf("    [1] 미결 전표      : %6ld %s\n", rec.draft_vouchers, h_n1 ? "NG" : "OK");
    printf("    [2] 불균형 전표    : %6ld %s\n", rec.imbalanced, h_n2 ? "NG" : "OK");
    printf("    [3] 0원 라인       : %6ld %s\n", rec.zero_lines, h_n3 ? "NG" : "OK");
    printf("    [4] 고아 라인      : %6ld %s\n", rec.orphan_lines, h_n4 ? "NG" : "OK");
    printf(">>> lg_closechk_batch COMMIT: 실패 %ld/4 항목 -> %s\n",
           rec.failed_items, (rec.failed_items == 0) ? "결산 가능" : "결산 보류");

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