/*
 * mm_grade_demote_batch.pgc - 매출 미달 가맹점 등급 강등 배치 (LEFT JOIN 집계 커서 + XA).
 *
 * 최근 N일 매출 합계가 현재 등급의 유지 기준(S>=5억, A>=1억, B>=1천만)에 미달하는
 * 활성 가맹점을 한 단계씩 강등(S->A->B->C)하고 GRADE_DEM 이력을 남긴다.
 * 승격은 하지 않는다 (승격은 mm_grade_recalc_batch 소관). ONE global XA transaction.
 * host 변수는 전용 카피북 mm_grade_demote_cpy.h 를 EXEC SQL INCLUDE.
 * Usage: mm_grade_demote_batch [DAYS=90]
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <atmi.h>
#include "mm_dbio.h"

/* 등급 유지 최소 매출 (원). 미달 시 한 단계 강등 */
static long keep_floor(const char *grade)
{
    if (grade[0] == 'S') return 500000000L;
    if (grade[0] == 'A') return 100000000L;
    if (grade[0] == 'B') return  10000000L;
    return 0;
}

static const char *one_down(const char *grade)
{
    if (grade[0] == 'S') return "A";
    if (grade[0] == 'A') return "B";
    return "C";
}

int main(int argc, char **argv)
{
    long demoted = 0;

    EXEC SQL INCLUDE mm_grade_demote_cpy;

    b_days = (argc > 1) ? atol(argv[1]) : 90;
    if (b_days < 1) b_days = 90;

    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 DECLARE gdm CURSOR FOR
        SELECT me.merchant_id, me.grade, coalesce(sum(ms.gross_amount), 0)
        FROM mm_merchant_ext me
        LEFT JOIN merchant_summary ms
               ON ms.merchant_id = me.merchant_id
              AND ms.biz_date >= current_date - :b_days
        WHERE me.status = 'ACTIVE' AND me.grade IN ('S', 'A', 'B')
        GROUP BY me.merchant_id, me.grade
        ORDER BY me.merchant_id;
    EXEC SQL OPEN gdm;
    if (sqlca.sqlcode < 0) { fprintf(stderr, "OPEN FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }

    for (;;) {
        EXEC SQL FETCH gdm INTO :b_merch, :b_grade, :b_gross;
        if (sqlca.sqlcode == 100) break;
        if (sqlca.sqlcode < 0) { fprintf(stderr, "FETCH FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); EXEC SQL CLOSE gdm; tpabort(0); return 1; }
        if (b_gross >= keep_floor(b_grade)) continue;
        strncpy(b_next, one_down(b_grade), sizeof(b_next)-1); b_next[sizeof(b_next)-1] = 0;
        if (mmdb_update_merchant_grade(b_merch, b_next) < 0) { EXEC SQL CLOSE gdm; tpabort(0); return 1; }
        if (mmdb_insert_merch_hist(b_merch, "GRADE_DEM", b_grade, b_next, "매출 미달 배치 강등") < 0) {
            EXEC SQL CLOSE gdm; tpabort(0); return 1;
        }
        demoted++;
    }
    EXEC SQL CLOSE gdm;

    if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
    printf(">>> mm_grade_demote_batch COMMIT: 기간=%ld일 강등=%ld건\n", b_days, demoted);

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