/*
 * MM_KYC_CHECK.pgc - mm 모듈 서비스 MM_KYC_CHECK (KYC/AML 점검 수행·판정).
 * 업무: mm_application.risk_score 를 근거로 check_type 별 판정을 수행하고
 *       mm_kyc 에 점검 결과 1건을 적재한다.
 *       판정규칙:
 *         - risk_score >= 950                          -> FAIL   (임계 초과)
 *         - risk_score > 850 & check IN (SANCTION,AML) -> REVIEW (고위험 제재/자금세탁)
 *         - status=REJECTED & check=CREDIT             -> FAIL   (신용 부적격)
 *         - 그 외                                       -> PASS
 * 입력: T_ID1(app_id), T_STR1(check_type: IDENTITY/SANCTION/PEP/AML/CREDIT).
 * 출력: T_STATUS=result, T_ARG1=score, T_ID1=kyc_id, T_RC.
 * 호출자 XA 브랜치에서 수행(EXEC SQL CONNECT 없음). mm_svr 가 tpsvrinit 에서 광고.
 */
#include "MM_KYC_CHECK.h"

#define KYC_FAIL_THRESHOLD   950   /* 임계 초과 -> 무조건 FAIL */
#define KYC_REVIEW_THRESHOLD 850   /* 제재/AML 고위험 -> REVIEW */

/* MM_KYC_CHECK - KYC/AML 점검 판정 및 mm_kyc 적재. */
void MM_KYC_CHECK(TPSVCINFO *p)
{
    UBFH *b = (UBFH *)p->data;
    char  check[24];
    int   valid_type = 0;
    EXEC SQL BEGIN DECLARE SECTION;
    long  h_app_id, h_risk, h_score, h_kyc_id, h_logid;
    char  h_check[24], h_mid[64], h_astatus[16], h_result[16];
    char  h_detail[160], h_svc[24], h_msg[200];
    EXEC SQL END DECLARE SECTION;

    /* 지역/호스트 변수 초기화 (DECLARE SECTION 밖) */
    h_app_id = h_risk = h_score = h_kyc_id = h_logid = 0;
    check[0] = 0;
    h_check[0] = h_mid[0] = h_astatus[0] = 0;
    strcpy(h_result, "PASS");
    strcpy(h_svc, "MM_KYC_CHECK");
    userlog("[MM_KYC_CHECK] KYC 점검 진입");

    /* [1] 입력 검증부 -------------------------------------------------- */
    h_app_id = getl(b, T_ID1);
    if (h_app_id <= 0) {
        setl(b, T_RC, 7101);
        Bchg(b, T_MSG, 0, "신청 ID(app_id) 필수", 0L);
        userlog("[MM_KYC_CHECK] app_id 검증 실패 id=%ld", h_app_id);
        FAIL(b);
    }
    gets_(b, T_STR1, check, sizeof(check));
    if (strcmp(check, "IDENTITY") == 0 || strcmp(check, "SANCTION") == 0 ||
        strcmp(check, "PEP")      == 0 || strcmp(check, "AML")      == 0 ||
        strcmp(check, "CREDIT")   == 0)
        valid_type = 1;
    if (!valid_type) {
        setl(b, T_RC, 7102);
        Bchg(b, T_MSG, 0, "check_type 은 IDENTITY/SANCTION/PEP/AML/CREDIT 중 하나", 0L);
        userlog("[MM_KYC_CHECK] 부적합 check_type=[%s]", check);
        FAIL(b);
    }
    strncpy(h_check, check, sizeof(h_check)-1); h_check[sizeof(h_check)-1] = 0;

    /* [2] 신청/리스크 조회부 ----------------------------------------- */
    EXEC SQL SELECT risk_score, coalesce(merchant_id,''), status
        INTO :h_risk, :h_mid, :h_astatus
        FROM mm_application WHERE app_id = :h_app_id;
    if (sqlca.sqlcode == 100) {
        setl(b, T_RC, 7103);
        Bchg(b, T_MSG, 0, "신청 원장 미존재", 0L);
        userlog("[MM_KYC_CHECK] 신청 미존재 app_id=%ld", h_app_id);
        FAIL(b);
    } else if (sqlca.sqlcode < 0) {
        userlog("[MM_KYC_CHECK] 신청 조회 오류 [%d]", sqlca.sqlcode);
        FAIL(b);
    }
    h_score = h_risk;
    userlog("[MM_KYC_CHECK] app_id=%ld risk=%ld status=%s check=%s",
            h_app_id, h_risk, h_astatus, h_check);

    /* [3] 판정부 (임계/제재/신용) ------------------------------------- */
    if (h_risk >= KYC_FAIL_THRESHOLD) {
        strcpy(h_result, "FAIL");
        userlog("[MM_KYC_CHECK] 리스크 임계 초과 risk=%ld -> FAIL", h_risk);
    } else if (h_risk > KYC_REVIEW_THRESHOLD &&
               (strcmp(h_check, "SANCTION") == 0 || strcmp(h_check, "AML") == 0)) {
        strcpy(h_result, "REVIEW");
        userlog("[MM_KYC_CHECK] 고위험 제재/AML -> REVIEW");
    } else if (strcmp(h_astatus, "REJECTED") == 0 && strcmp(h_check, "CREDIT") == 0) {
        strcpy(h_result, "FAIL");
        userlog("[MM_KYC_CHECK] 반려 신청 신용점검 -> FAIL");
    } else {
        strcpy(h_result, "PASS");
    }

    /* [4] 본처리부: mm_kyc 적재 (kyc_id = nextval mm_kyc_seq) ---------- */
    EXEC SQL SELECT nextval('mm_kyc_seq') INTO :h_kyc_id;
    if (sqlca.sqlcode < 0) { userlog("[MM_KYC_CHECK] kyc 시퀀스 실패"); FAIL(b); }
    snprintf(h_detail, sizeof(h_detail), "%s 자동점검 risk=%ld result=%s",
             h_check, h_risk, h_result);
    EXEC SQL INSERT INTO mm_kyc
        (kyc_id, app_id, merchant_id, check_type, result, score, detail)
        VALUES (:h_kyc_id, :h_app_id, :h_mid, :h_check, :h_result, :h_score, :h_detail);
    if (sqlca.sqlcode < 0) {
        userlog("[MM_KYC_CHECK] mm_kyc 적재 실패 [%d]", sqlca.sqlcode);
        setl(b, T_RC, 7104);
        Bchg(b, T_MSG, 0, "KYC 점검 결과 적재 실패", 0L);
        FAIL(b);
    }

    /* [5] 이력/감사 적재부 (cm_log) ----------------------------------- */
    EXEC SQL SELECT nextval('cm_log_seq') INTO :h_logid;
    if (sqlca.sqlcode < 0) { userlog("[MM_KYC_CHECK] 로그 시퀀스 실패"); FAIL(b); }
    snprintf(h_msg, sizeof(h_msg), "MM_KYC_CHECK app=%ld type=%s result=%s score=%ld kyc=%ld",
             h_app_id, h_check, h_result, h_score, h_kyc_id);
    EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
        VALUES (:h_logid, :h_svc,
                CASE WHEN :h_result = 'PASS' THEN 'I' ELSE 'W' END,
                :h_msg, current_date);
    if (sqlca.sqlcode < 0) { userlog("[MM_KYC_CHECK] 감사 로그 적재 실패 [%d]", sqlca.sqlcode); FAIL(b); }

    /* [6] 응답부 (출력 필드 설정) ------------------------------------- */
    Bchg(b, T_STATUS, 0, h_result, 0L);
    setl(b, T_ARG1, h_score);
    setl(b, T_ID1, h_kyc_id);
    setl(b, T_RC, 0);

    /* [7] 완료 로깅 --------------------------------------------------- */
    userlog("[MM_KYC_CHECK] 점검 완료 app_id=%ld type=%s result=%s kyc_id=%ld",
            h_app_id, h_check, h_result, h_kyc_id);
    OK(b);
}

/* vim: set ts=4 sw=4 et smartindent: */
