/*
 * CM_AMT_HANGUL.pgc - cm 모듈 서비스 CM_AMT_HANGUL (one service = one file).
 * 금액 한글변환(순수 계산): 정수 금액을 4자리(만 단위) 그룹으로 쪼개
 * 일~구천 + 만/억/조 단위를 붙인 한글 금액 표기로 변환한다(영수증/전표용).
 * 0 은 "영원", 음수는 "마이너스" 접두. no EXEC SQL.
 */
#include "CM_AMT_HANGUL.h"

/* ----- service-local pure tables ----- */
static const char *CM_HAN_DIGIT[] =
    { "", "일", "이", "삼", "사", "오", "육", "칠", "팔", "구" };
static const char *CM_HAN_POS[]  = { "", "십", "백", "천" };
static const char *CM_HAN_UNIT[] = { "", "만", "억", "조" };

/* 0~9999 한 그룹을 한글로. 반환 = 이어붙인 길이 */
static int cm_han_grp(long v, char *dst)
{
    int pos, dig, n = 0;
    for (pos = 3; pos >= 0; pos--) {
        long div = 1; int k;
        for (k = 0; k < pos; k++) div *= 10;
        dig = (int)(v / div % 10);
        if (dig == 0) continue;
        if (!(dig == 1 && pos > 0))                  /* 일십/일백은 십/백으로 */
            n += sprintf(dst + n, "%s", CM_HAN_DIGIT[dig]);
        n += sprintf(dst + n, "%s", CM_HAN_POS[pos]);
    }
    return n;
}


/* ------------------------------------------------------------------ */
/* 원 서비스 핵심 로직 - 입출력 필드 계약 보존 (0=정상, -1=실패).        */
/* ------------------------------------------------------------------ */
static int CM_AMT_HANGUL__core(TPSVCINFO *p)
{
    UBFH *b = (UBFH *)p->data;
    char out[256], grp[64];
    long amt, part[4];
    int gi, top = -1, n = 0;

    amt = getl(b, T_AMOUNT);
    if (amt < 0) { n += sprintf(out, "마이너스"); amt = -amt; }
    if (amt >= 10000000000000000L) { setl(b, T_RC, 1); return -1; }  /* 조 단위 초과 */

    for (gi = 0; gi < 4; gi++) {                     /* 만 단위 그룹 분해 */
        part[gi] = amt % 10000;
        amt /= 10000;
        if (part[gi] != 0) top = gi;
    }
    if (top < 0) {
        strcpy(out, "영원");
    } else {
        for (gi = top; gi >= 0; gi--) {
            if (part[gi] == 0) continue;
            cm_han_grp(part[gi], grp);
            n += sprintf(out + n, "%s%s", grp, CM_HAN_UNIT[gi]);
        }
        sprintf(out + n, "원");
    }
    sets_(b, T_STR4, out);
    return 0;
    return 0;
}

/* CM_AMT_HANGUL 심화용 보조 판정 - 처리등급 산정. */
static int CM_AMT_HANGUL__grade(long v)
{
    if (v <= 0)          return 0;   /* 대상없음 */
    if (v < 17L)         return 1;   /* 소량 */
    if (v < 1007L)         return 2;   /* 보통 */
    if (v < 101007L)         return 3;   /* 대량 */
    return 4;                        /* 초대량 */
}

/* CM_AMT_HANGUL - * CM_AMT_HANGUL.pgc - cm 모듈 서비스 CM_AMT_HANGUL (one service =. 심화: 검증/정책조회/업무분기/감사/집계 보강. */
void CM_AMT_HANGUL(TPSVCINFO *p)
{
    UBFH *b = (UBFH *)p->data;
    EXEC SQL BEGIN DECLARE SECTION;
    char hz_bizdate[16];
    char hz_key[64];
    char hz_pval[128];
    char hz_txt[128];
    long hz_cnt;
    long hz_sum;
    long hz_v1;
    long hz_v2;
    EXEC SQL END DECLARE SECTION;
    long rc = 0, core_rc = 0, aud_id = 0, band = 0, grade = 0;
    long in_amt = 0, in_arg = 0, agg = 0, policy = 0;
    char ins[64], msg[200];
    int vlen = 0, vi = 0;

    userlog("CM_AMT_HANGUL 진입: * CM_AMT_HANGUL.pgc - cm 모듈 서비스 CM_AMT_HANGUL (one service = (svc=CM_AMT_HANGUL)");

    /* 1) 입력 검증부 - 필수/범위/형식 확인. */
    if (cmdb_get_param("BIZ_DATE", hz_bizdate) < 0)
        strcpy(hz_bizdate, "2026-07-19");
    gets_(b, T_BIZDATE, ins, sizeof(ins));
    if (ins[0] != 0) {
        int yy = 0, mm = 0, dd = 0;
        if (sscanf(ins, "%d-%d-%d", &yy, &mm, &dd) != 3) {
            Bchg(b, T_MSG, 0, "영업일 형식 오류(YYYY-MM-DD)", 0L); FAIL(b);
        }
        if (mm < 1 || mm > 12 || dd < 1 || dd > 31) {
            Bchg(b, T_MSG, 0, "영업일 월/일 범위 오류", 0L); FAIL(b);
        }
        strncpy(hz_bizdate, ins, sizeof(hz_bizdate)-1);
        hz_bizdate[sizeof(hz_bizdate)-1] = 0;
    }
    in_amt = getl(b, T_AMOUNT);
    in_arg = getl(b, T_ARG1);
    if (in_amt < 0) {
        Bchg(b, T_MSG, 0, "금액이 음수입니다", 0L); FAIL(b);
    }
    gets_(b, T_STR1, ins, sizeof(ins));
    for (vi = 0; ins[vi]; vi++) vlen++;
    if (vlen > 60) {
        Bchg(b, T_MSG, 0, "입력 문자열이 너무 깁니다", 0L); FAIL(b);
    }

    /* 2) 정책/마스터 조회부 - 관련 기준정보 로드 후 분기. */
    if (cmdb_get_param("VAT_RATE", hz_pval) == 0) policy = atol(hz_pval);
    else policy = 10;   /* 기본 부가세율 */
    EXEC SQL SELECT count(*) INTO :hz_cnt FROM cm_log
        WHERE svc_name = 'CM_AMT_HANGUL' AND biz_date = :hz_bizdate;
    if (sqlca.sqlcode < 0) { userlog("CM_AMT_HANGUL 처리이력 조회 오류"); }
    else { policy += (hz_cnt % 7); }   /* 반복호출 보정 */

    /* 3) 업무규칙 분기부 - 상태/구간/등급별 경로 분리. */
    band = in_amt + in_arg;
    if (band <= 0) {
        grade = 0; userlog("CM_AMT_HANGUL 무금액 요청 - 조회전용 경로");
    } else if (band < 107L) {
        grade = 1; band = band + acq_fee(band, 25);   /* 소액 수수료 가산 */
    } else if (band < 11007L) {
        grade = 2; band = band + acq_vat(band / 10);  /* 중액 부가세 */
    } else {
        grade = 3; band = band + acq_wht_amt(band, 2200); /* 대액 원천 */
    }
    if (grade >= 3 && band > 110070L) {
        userlog("CM_AMT_HANGUL 임계 초과 - 감사강화 band=%ld", band);
    }

    /* 4) 본처리부 - 원 서비스 핵심 로직 수행(계산/DB 반영). */
    core_rc = CM_AMT_HANGUL__core(p);
    if (core_rc != 0) {
        Bchg(b, T_MSG, 0, "핵심 처리 실패 - 롤백", 0L);
        userlog("CM_AMT_HANGUL 실패: core_rc=%ld", core_rc);
        FAIL(b);
    }

    /* 5) 이력/감사 적재부 - cm_log 에 처리 요약 기록. */
    grade = CM_AMT_HANGUL__grade(in_amt + in_arg + agg);
    snprintf(msg, sizeof(msg), "CM_AMT_HANGUL 처리 grade=%ld policy=%ld agg=%ld",
             grade, policy, agg);
    aud_id = cmdb_log("CM_AMT_HANGUL", grade >= 3 ? "W" : "I", msg, hz_bizdate);
    if (aud_id < 0) {
        Bchg(b, T_MSG, 0, "감사 로그 적재 실패", 0L);
        FAIL(b);
    }

    /* 6) 집계/요약 갱신부 - 처리 결과 재집계(SELECT 기반). */
    EXEC SQL SELECT count(*) INTO :hz_v1 FROM cm_log
        WHERE biz_date = :hz_bizdate AND svc_name = 'CM_AMT_HANGUL';
    agg = (sqlca.sqlcode == 0) ? hz_v1 : 0;   /* 당일 자기 처리건수 */
    if (agg > 1007L)
        userlog("CM_AMT_HANGUL 집계 임계 agg=%ld", agg);

    /* 7) 예외/보상부 - 집계 재조회 실패시 전체 롤백. */
    if (sqlca.sqlcode < 0) {
        userlog("CM_AMT_HANGUL 집계 조회 오류 sqlcode=%d", sqlca.sqlcode);
        Bchg(b, T_MSG, 0, "집계 재조회 오류", 0L);
        FAIL(b);
    }

    /* 8) 응답부 - 결과 필드 채움. */
    setl(b, T_ARG8, aud_id);
    setl(b, T_ARG7, agg);
    setl(b, T_ARG6, grade);

    userlog("CM_AMT_HANGUL 완료: aud_id=%ld grade=%ld agg=%ld", aud_id, grade, agg);
    OK(b);
}
