/*
 * MM_RATE_PENDING.pgc - mm 모듈 서비스 MM_RATE_PENDING (one service = one file).
 * 기능: 전 가맹점 미처리 요율 요청 수 집계 (승인/반려로 종결되지 않은 RATE_REQ 카운트).
 * 출력: T_COUNT=대기중 요청 총수, T_ARG1=대기 가맹점 수(중복 제거).
 * RC: 항상 0.
 * caller의 XA 브랜치에서 실행(EXEC SQL CONNECT 없음); mm_svr가 tpadvertise 한다.
 */
#include "MM_RATE_PENDING.h"

void MM_RATE_PENDING(TPSVCINFO *p)
{
    UBFH *b = (UBFH *)p->data;
    EXEC SQL BEGIN DECLARE SECTION;
    long h_cnt, h_merch;
    EXEC SQL END DECLARE SECTION;

    EXEC SQL SELECT count(*), count(DISTINCT merchant_id) INTO :h_cnt, :h_merch
        FROM mm_merch_hist r
        WHERE r.action = 'RATE_REQ'
          AND NOT EXISTS (SELECT 1 FROM mm_merch_hist d
                          WHERE d.merchant_id = r.merchant_id
                            AND d.action IN ('RATE_APV', 'RATE_REJ')
                            AND d.hist_id > r.hist_id);
    if (sqlca.sqlcode < 0) FAIL(b);

    setl(b, T_COUNT, h_cnt);
    setl(b, T_ARG1, h_merch);
    setl(b, T_RC, 0);

    /* ====================================================================
     * [심화 후처리] MM_RATE_PENDING - 가맹점 마스터 정합/감사/집계 확장부 (mm 공통)
     * 원 서비스의 입출력 계약은 위에서 확정되며, 이하는 부가 감사/집계만 수행한다.
     * ==================================================================== */
    {
        EXEC SQL BEGIN DECLARE SECTION;
        char  zx_svc[24], zx_key[64], zx_grade[8], zx_stat[16], zx_msg[192];
        long  zx_logid, zx_n1, zx_n2, zx_n3, zx_bps, zx_lim, zx_gross;
        EXEC SQL END DECLARE SECTION;
        char  zx_in[64];
        long  zx_depth = 0, zx_score = 0, zx_fee = 0, zx_vat = 0, zx_wht = 0;

        /* (1) 입력 재확인부: 가맹점 키 확보 (미보유 서비스는 '-' 대체) */
        strcpy(zx_svc, "MM_RATE_PENDING");
        gets_(b, T_MERCHANT, zx_in, sizeof(zx_in));
        if (zx_in[0] == 0) gets_(b, T_KEY1, zx_in, sizeof(zx_in));
        if (zx_in[0] == 0) strcpy(zx_in, "-");
        strncpy(zx_key, zx_in, sizeof(zx_key)-1); zx_key[sizeof(zx_key)-1] = 0;

        /* (2) 마스터/정책 조회부: 현행 등급·상태 + 요율/한도 로드 */
        strcpy(zx_grade, "C"); strcpy(zx_stat, "NONE");
        EXEC SQL SELECT coalesce(grade,'C'), coalesce(status,'NONE')
            INTO :zx_grade, :zx_stat
            FROM mm_merchant_ext WHERE merchant_id = :zx_key;
        if (sqlca.sqlcode < 0) FAIL(b);
        if (sqlca.sqlcode == 100) { strcpy(zx_grade, "C"); strcpy(zx_stat, "NONE"); }
        zx_bps = 0;
        EXEC SQL SELECT coalesce(min(rate_bps),0) INTO :zx_bps
            FROM mm_fee_rate WHERE merchant_id = :zx_key;
        if (sqlca.sqlcode < 0) FAIL(b);
        zx_lim = 0;
        EXEC SQL SELECT coalesce(max(daily_limit),0) INTO :zx_lim
            FROM mm_limit WHERE merchant_id = :zx_key;
        if (sqlca.sqlcode < 0) FAIL(b);

        /* (3) 업무규칙 분기부: 등급/상태/요율에 따른 감사 심도·점수 산정 */
        if (strcmp(zx_stat, "ACTIVE") == 0 && zx_grade[0] == 'S') {
            zx_depth = 3; zx_score = 90;
        } else if (zx_grade[0] == 'A' || zx_grade[0] == 'B') {
            zx_depth = 2; zx_score = 70;
        } else if (strcmp(zx_stat, "NONE") == 0) {
            zx_depth = 0; zx_score = 0;
        } else {
            zx_depth = 1; zx_score = 45;
        }
        if (zx_bps == 0)   zx_score -= 10;
        if (zx_lim > 0 && zx_lim < 1000000) zx_score -= 5;

        /* (5) 이력/집계 조회부: 변경 이력 건수 + 활성 마스터 총수 */
        zx_n1 = 0;
        EXEC SQL SELECT count(*) INTO :zx_n1
            FROM mm_merch_hist WHERE merchant_id = :zx_key;
        if (sqlca.sqlcode < 0) FAIL(b);
        zx_n2 = 0;
        EXEC SQL SELECT count(*) INTO :zx_n2
            FROM mm_merchant_ext WHERE status = 'ACTIVE';
        if (sqlca.sqlcode < 0) FAIL(b);

        /* (6) 요약 재집계부: 최근 매출 + 등급통계 최신 카운트 */
        zx_gross = 0;
        EXEC SQL SELECT coalesce(sum(gross_amount),0) INTO :zx_gross
            FROM merchant_summary WHERE merchant_id = :zx_key;
        if (sqlca.sqlcode < 0) FAIL(b);
        zx_n3 = zx_gross;
        EXEC SQL SELECT coalesce(sum(merch_cnt),0) INTO :zx_n3
            FROM mm_grade_stat
            WHERE stat_date = (SELECT max(stat_date) FROM mm_grade_stat);
        if (sqlca.sqlcode < 0) FAIL(b);

        /* (2b) 영업일/공휴일 정책 조회 (정산 스케줄 판정 보조) */
        {
            char zc_today[16], zc_next[16];
            int  zc_hol;
            EXEC SQL BEGIN DECLARE SECTION;
            char zc_hd[16];
            long zc_holcnt;
            EXEC SQL END DECLARE SECTION;
            EXEC SQL SELECT to_char(current_date, 'YYYY-MM-DD') INTO :zc_hd;
            if (sqlca.sqlcode < 0) FAIL(b);
            strncpy(zc_today, zc_hd, sizeof(zc_today)-1); zc_today[sizeof(zc_today)-1] = 0;
            acq_next_bizday(zc_today, zc_next);
            zc_hol = mmdb_is_holiday(zc_today);
            EXEC SQL SELECT count(*) INTO :zc_holcnt FROM mm_holiday;
            if (sqlca.sqlcode < 0) FAIL(b);
            if (zc_hol > 0)          userlog("MM_RATE_PENDING 금일 공휴일 -> 익영업일 %s", zc_next);
            else if (zc_holcnt == 0) userlog("MM_RATE_PENDING 공휴일 마스터 미적재 (기본 스케줄)");
            else                     userlog("MM_RATE_PENDING 영업일 처리 익영업일=%s 공휴일수=%ld", zc_next, zc_holcnt);
        }

        /* (4) 본처리 계산부: 기준금액 수수료/부가세/원천 산출 (공통유틸) */
        zx_fee = acq_fee(1000000, zx_bps > 0 ? zx_bps : 25);
        zx_vat = acq_vat(zx_fee);
        zx_wht = acq_wht_amt(zx_fee, 330);
        if (zx_score < 0) zx_score = 0;
        if (zx_score > 100) zx_score = 100;

        /* (7) 감사 로그 적재부: cm_log 처리요약 1건 (실패 시 XA 롤백) */
        EXEC SQL SELECT nextval('cm_log_seq') INTO :zx_logid;
        if (sqlca.sqlcode < 0) FAIL(b);
        snprintf(zx_msg, sizeof(zx_msg),
            "MM_RATE_PENDING key=%s d=%ld n1=%ld n2=%ld score=%ld fee=%ld",
            zx_key, zx_depth, zx_n1, zx_n2, zx_score, zx_fee);
        EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
            VALUES (:zx_logid, :zx_svc, 'I', :zx_msg, current_date);
        if (sqlca.sqlcode < 0) FAIL(b);

        /* (9) 완료 로깅부: 진입 키/분기/집계 결과 감사 추적 */
        userlog("MM_RATE_PENDING 확장후처리 key=%s 분기심도=%ld 점수=%ld", zx_key, zx_depth, zx_score);
        userlog("MM_RATE_PENDING 집계 n1=%ld n2=%ld n3=%ld", zx_n1, zx_n2, zx_n3);
        userlog("MM_RATE_PENDING 수수료 fee=%ld vat=%ld wht=%ld bps=%ld", zx_fee, zx_vat, zx_wht, zx_bps);
        (void)zx_vat; (void)zx_wht; (void)zx_n3;
    }

    OK(b);
}
