/*
 * MG_CLEARING_INQ.pgc - mg 모듈 서비스 MG_CLEARING_INQ (one service = one file).
 * ISO 8583 클리어링 메시지(mg_clearing) 조회. 승인전문(mg_msg_log)과 분리된
 * 클리어링 단계의 전문 클래스(PRESENTMENT/CHARGEBACK/REPRESENT/RECONCILE/
 * FEE_COLLECT/FILE_REJECT)를 집계·조회한다.
 * 입력계약:
 *   T_PURCHASE_ID  (선택) 특정 매입건의 클리어링 이력 조회
 *   T_STR1         (선택) 특정 msg_class 필터
 *   T_BIZDATE      (선택) 영업일
 * 출력계약:
 *   T_COUNT=총 메시지 건수, T_ARG1=DUAL 건수, T_ARG2=SINGLE 건수,
 *   T_AMT1=총 금액, T_STR2=대표 MTI, T_STATUS=조회상태.
 * Runs on caller's XA branch (no EXEC SQL CONNECT). Advertised by mg_svr.
 */
#include "MG_CLEARING_INQ.h"

void MG_CLEARING_INQ(TPSVCINFO *p)
{
    UBFH *b = (UBFH *)p->data;
    const char *SVC = "MG_CLEARING_INQ";
    char in_class[24], in_bizdate[16];
    long in_pid;

    EXEC SQL BEGIN DECLARE SECTION;
    long  h_pid;
    char  h_class[24];
    char  h_bizdate[16];
    long  h_total, h_dual, h_single, h_amt;
    long  h_present, h_chargeback, h_represent, h_reconcile, h_feecol, h_reject;
    char  h_top_mti[8];
    EXEC SQL END DECLARE SECTION;

    userlog("%s 진입: ISO 8583 클리어링 메시지 조회", SVC);

    /* --- 1) 입력 검증/수집부 ------------------------------------------- */
    in_pid = getl(b, T_PURCHASE_ID);
    gets_(b, T_STR1, in_class, sizeof(in_class));
    gets_(b, T_BIZDATE, in_bizdate, sizeof(in_bizdate));
    h_pid = in_pid;
    strncpy(h_class, in_class, sizeof(h_class) - 1); h_class[sizeof(h_class) - 1] = 0;
    strncpy(h_bizdate, in_bizdate, sizeof(h_bizdate) - 1); h_bizdate[sizeof(h_bizdate) - 1] = 0;
    if (h_class[0] == 0) strcpy(h_class, "ALL");
    if (h_bizdate[0] == 0) strcpy(h_bizdate, "ALL");

    h_total = h_dual = h_single = h_amt = 0;
    h_present = h_chargeback = h_represent = h_reconcile = h_feecol = h_reject = 0;
    strcpy(h_top_mti, "");

    /* --- 2) 본 조회부: 필터 조합별 집계 -------------------------------- */
    if (h_pid > 0) {
        /* 특정 매입건의 클리어링 이력 (라이프사이클 추적) */
        EXEC SQL SELECT count(*),
                        coalesce(sum(CASE WHEN msg_type='DUAL'   THEN 1 ELSE 0 END), 0),
                        coalesce(sum(CASE WHEN msg_type='SINGLE' THEN 1 ELSE 0 END), 0),
                        coalesce(sum(amount), 0)
            INTO :h_total, :h_dual, :h_single, :h_amt
            FROM mg_clearing WHERE purchase_id = :h_pid;
        if (sqlca.sqlcode < 0) {
            userlog("%s: 매입건 클리어링 조회 실패 [%d]", SVC, sqlca.sqlcode);
            setl(b, T_RC, 9501); sets_(b, T_MSG, "클리어링 조회 실패"); FAIL(b);
        }
    } else {
        /* 전체(또는 클래스/영업일 필터) 집계 */
        EXEC SQL SELECT count(*),
                        coalesce(sum(CASE WHEN msg_type='DUAL'   THEN 1 ELSE 0 END), 0),
                        coalesce(sum(CASE WHEN msg_type='SINGLE' THEN 1 ELSE 0 END), 0),
                        coalesce(sum(amount), 0)
            INTO :h_total, :h_dual, :h_single, :h_amt
            FROM mg_clearing
            WHERE (:h_class = 'ALL'   OR msg_class = :h_class)
              AND (:h_bizdate = 'ALL' OR to_char(biz_date,'YYYY-MM-DD') = :h_bizdate);
        if (sqlca.sqlcode < 0) {
            userlog("%s: 클리어링 집계 실패 [%d]", SVC, sqlca.sqlcode);
            setl(b, T_RC, 9502); sets_(b, T_MSG, "클리어링 집계 실패"); FAIL(b);
        }
    }

    /* --- 3) 메시지 클래스별 분해 (전체 조회일 때만) -------------------- */
    if (h_pid <= 0) {
        EXEC SQL SELECT
            coalesce(sum(CASE WHEN msg_class='PRESENTMENT' THEN 1 ELSE 0 END),0),
            coalesce(sum(CASE WHEN msg_class='CHARGEBACK'  THEN 1 ELSE 0 END),0),
            coalesce(sum(CASE WHEN msg_class='REPRESENT'   THEN 1 ELSE 0 END),0),
            coalesce(sum(CASE WHEN msg_class='RECONCILE'   THEN 1 ELSE 0 END),0),
            coalesce(sum(CASE WHEN msg_class='FEE_COLLECT' THEN 1 ELSE 0 END),0),
            coalesce(sum(CASE WHEN status='REJECTED'       THEN 1 ELSE 0 END),0)
            INTO :h_present, :h_chargeback, :h_represent, :h_reconcile, :h_feecol, :h_reject
            FROM mg_clearing
            WHERE (:h_bizdate = 'ALL' OR to_char(biz_date,'YYYY-MM-DD') = :h_bizdate);
        if (sqlca.sqlcode < 0) { userlog("%s: 클래스 분해 실패 [%d]", SVC, sqlca.sqlcode); }
    }

    /* --- 4) 대표 MTI 조회 (건수 최다 클래스의 MTI) --------------------- */
    EXEC SQL SELECT mti INTO :h_top_mti FROM mg_clearing
        WHERE (:h_class = 'ALL' OR msg_class = :h_class)
          AND (:h_pid <= 0 OR purchase_id = :h_pid)
        GROUP BY mti ORDER BY count(*) DESC LIMIT 1;
    if (sqlca.sqlcode == 100) strcpy(h_top_mti, "-");

    /* --- 5) 업무규칙: 이상신호 판정(거부 메시지 존재시 경보) ----------- */
    if (h_reject > 0)
        userlog("%s 경보: 거부(REJECTED) 클리어링 메시지 %ld건", SVC, h_reject);

    /* --- 6) 응답 전문 구성부 ------------------------------------------- */
    setl(b, T_COUNT, h_total);
    setl(b, T_ARG1, h_dual);
    setl(b, T_ARG2, h_single);
    setl(b, T_AMT1, h_amt);
    setl(b, T_AMT2, h_present);
    setl(b, T_AMT3, h_chargeback);
    setl(b, T_ARG3, h_reconcile);
    setl(b, T_ARG4, h_feecol);
    sets_(b, T_STR2, h_top_mti);
    setl(b, T_RC, 0);
    sets_(b, T_STATUS, h_total > 0 ? "FOUND" : "EMPTY");

    /* --- 7) 로깅부 ----------------------------------------------------- */
    userlog("%s 완료: total=%ld dual=%ld single=%ld amt=%ld present=%ld cb=%ld recon=%ld",
            SVC, h_total, h_dual, h_single, h_amt, h_present, h_chargeback, h_reconcile);
    OK(b);
}
